summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Smirnov <[email protected]>2025-06-18 14:38:34 +0000
committerAlexander Smirnov <[email protected]>2025-06-18 14:38:34 +0000
commitf0aab26e5fffb68cd8ae3be804d246bb8337a784 (patch)
treece6f8a1847719c9d8a7acc5c654e951ac8a4bf87
parent68fd8a82ce8a9b7dd18072f3941171d8548bb0e1 (diff)
parent826c4b4f2be8243bde08a51459dabfb2f271b289 (diff)
Merge pull request #19782 from ydb-platform/merge-libs-250618-0050
-rw-r--r--build/conf/java.conf4
-rw-r--r--build/export_generators/ide-gradle/javac_flags.jinja7
-rw-r--r--build/export_generators/ide-gradle/jvm_args.jinja24
-rw-r--r--build/export_generators/ide-gradle/source_sets.jinja3
-rw-r--r--build/external_resources/gdb/resources.json4
-rw-r--r--build/external_resources/ymake/public.resources.json10
-rw-r--r--build/external_resources/ymake/resources.json10
-rw-r--r--build/mapping.conf.json16
-rw-r--r--build/platform/test_tool/host.ya.make.inc10
-rw-r--r--build/platform/test_tool/host_os.ya.make.inc10
-rw-r--r--build/ymake.core.conf25
-rw-r--r--contrib/libs/ftxui/.yandex_meta/__init__.py11
-rw-r--r--contrib/libs/ftxui/.yandex_meta/override.nix3
-rw-r--r--contrib/libs/ftxui/ya.make7
-rw-r--r--library/cpp/protobuf/json/json2proto.cpp53
-rw-r--r--library/cpp/protobuf/json/ut/json2proto_ut.cpp79
-rwxr-xr-xya20
-rw-r--r--ydb/ci/rightlib.txt2
-rw-r--r--yql/essentials/cfg/tests/gateways.conf5
-rw-r--r--yql/essentials/core/facade/yql_facade.cpp1
-rw-r--r--yql/essentials/core/type_ann/type_ann_blocks.cpp8
-rw-r--r--yql/essentials/core/type_ann/type_ann_blocks.h4
-rw-r--r--yql/essentials/core/type_ann/type_ann_core.cpp249
-rw-r--r--yql/essentials/core/type_ann/type_ann_list.cpp66
-rw-r--r--yql/essentials/core/type_ann/type_ann_list.h23
-rw-r--r--yql/essentials/core/type_ann/type_ann_pg.cpp2
-rw-r--r--yql/essentials/core/type_ann/type_ann_types.cpp64
-rw-r--r--yql/essentials/core/type_ann/type_ann_types.h6
-rw-r--r--yql/essentials/core/type_ann/type_ann_wide.cpp4
-rw-r--r--yql/essentials/core/type_ann/type_ann_wide.h2
-rw-r--r--yql/essentials/core/yql_expr_type_annotation.cpp19
-rw-r--r--yql/essentials/core/yql_expr_type_annotation.h7
-rw-r--r--yql/essentials/core/yql_type_annotation.h1
-rw-r--r--yql/essentials/docs/en/udf/list/string.md4
-rw-r--r--yql/essentials/docs/ru/udf/list/string.md4
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_block_coalesce.cpp25
-rw-r--r--yql/essentials/minikql/comp_nodes/mkql_block_exists.cpp4
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_block_coalesce_ut.cpp95
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_block_exists_ut.cpp15
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/mkql_block_helper.h111
-rw-r--r--yql/essentials/minikql/comp_nodes/ut/ya.make.inc2
-rw-r--r--yql/essentials/minikql/computation/mkql_block_impl.cpp8
-rw-r--r--yql/essentials/minikql/mkql_runtime_version.h2
-rw-r--r--yql/essentials/minikql/mkql_type_builder.cpp17
-rw-r--r--yql/essentials/minikql/mkql_type_helper.h27
-rw-r--r--yql/essentials/providers/common/proto/gateways_config.proto9
-rw-r--r--yql/essentials/public/purecalc/common/type_from_schema.cpp4
-rw-r--r--yql/essentials/public/purecalc/common/worker_factory.cpp1
-rw-r--r--yql/essentials/public/purecalc/ut/fake_spec.cpp46
-rw-r--r--yql/essentials/public/purecalc/ut/fake_spec.h1
-rw-r--r--yql/essentials/public/purecalc/ut/test_sql.cpp21
-rw-r--r--yql/essentials/public/udf/arrow/dispatch_traits.h5
-rw-r--r--yql/essentials/public/udf/arrow/util.h15
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/column.cpp116
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/column.h13
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/global.cpp25
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/global.h11
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/global_ut.cpp20
-rw-r--r--yql/essentials/sql/v1/complete/analysis/global/ya.make1
-rw-r--r--yql/essentials/sql/v1/complete/analysis/local/local.cpp54
-rw-r--r--yql/essentials/sql/v1/complete/analysis/local/local.h7
-rw-r--r--yql/essentials/sql/v1/complete/analysis/local/parser_call_stack.cpp12
-rw-r--r--yql/essentials/sql/v1/complete/analysis/local/parser_call_stack.h2
-rw-r--r--yql/essentials/sql/v1/complete/antlr4/c3i.h2
-rw-r--r--yql/essentials/sql/v1/complete/antlr4/c3t.h51
-rw-r--r--yql/essentials/sql/v1/complete/core/name.cpp8
-rw-r--r--yql/essentials/sql/v1/complete/core/name.h9
-rw-r--r--yql/essentials/sql/v1/complete/core/statement.cpp1
-rw-r--r--yql/essentials/sql/v1/complete/core/ya.make2
-rw-r--r--yql/essentials/sql/v1/complete/name/object/schema.h16
-rw-r--r--yql/essentials/sql/v1/complete/name/object/simple/schema.cpp63
-rw-r--r--yql/essentials/sql/v1/complete/name/object/simple/schema.h7
-rw-r--r--yql/essentials/sql/v1/complete/name/object/simple/static/schema.cpp45
-rw-r--r--yql/essentials/sql/v1/complete/name/object/simple/static/schema.h3
-rw-r--r--yql/essentials/sql/v1/complete/name/service/name_service.h19
-rw-r--r--yql/essentials/sql/v1/complete/name/service/ranking/ranking.cpp3
-rw-r--r--yql/essentials/sql/v1/complete/name/service/schema/name_service.cpp37
-rw-r--r--yql/essentials/sql/v1/complete/name/service/static/name_service.cpp57
-rw-r--r--yql/essentials/sql/v1/complete/sql_complete.cpp54
-rw-r--r--yql/essentials/sql/v1/complete/sql_complete.h17
-rw-r--r--yql/essentials/sql/v1/complete/sql_complete_ut.cpp146
-rw-r--r--yql/essentials/sql/v1/complete/syntax/format.cpp32
-rw-r--r--yql/essentials/sql/v1/complete/syntax/grammar.cpp6
-rw-r--r--yql/essentials/sql/v1/complete/syntax/grammar.h1
-rw-r--r--yql/essentials/sql/v1/complete/syntax/ya.make1
-rw-r--r--yql/essentials/tests/common/test_framework/yql_utils.py2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructExtraItemsFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructNameMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTargetNameMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTargetTypeMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTypeMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleExtraItemsFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleNotEnoughItemsFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleTargetTypeMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleTypeMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralUnderlyingTypeMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructExtraItemsFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructNameMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTargetNameMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTargetTypeMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTypeMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleNotEnoughItemsFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleTargetTypeMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleTypeMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantUnderlyingTypeMismatchFail.yqls2
-rw-r--r--yql/essentials/tests/sql/minirun/part0/canondata/test.test_expr-dict_common_type--Results_/extracted6
-rw-r--r--yql/essentials/tools/yql_complete/yql_complete.cpp21
-rw-r--r--yql/essentials/udfs/common/string/string_udf.cpp12
-rw-r--r--yql/essentials/udfs/common/string/test/canondata/result.json5
-rw-r--r--yql/essentials/udfs/common/string/test/canondata/test.test_AsciiCmpIgnoreCase_AllAlternatives_2025_01_/results.txt121
-rw-r--r--yql/essentials/udfs/common/string/test/canondata/test.test_AsciiContainsIgnoreCase_2025_01_/extracted20
-rw-r--r--yql/essentials/udfs/common/string/test/canondata/test.test_AsciiContainsIgnoreCase_2025_01_scan_/extracted20
-rw-r--r--yql/essentials/udfs/common/string/test/cases/AsciiCmpIgnoreCase_AllAlternatives_2025_01.cfg2
-rw-r--r--yql/essentials/udfs/common/string/test/cases/AsciiCmpIgnoreCase_AllAlternatives_2025_01.sql10
-rw-r--r--yql/essentials/udfs/common/string/test/cases/AsciiContainsIgnoreCase_2025_01.sql2
-rw-r--r--yql/essentials/udfs/common/string/test/cases/AsciiContainsIgnoreCase_2025_01_scan.sql2
-rw-r--r--yql/essentials/utils/backtrace/backtrace_lib.cpp9
-rw-r--r--yql/essentials/utils/failure_injector/failure_injector.cpp12
-rw-r--r--yql/essentials/utils/failure_injector/failure_injector.h4
-rw-r--r--yql/essentials/utils/fetch/fetch.cpp30
-rw-r--r--yql/essentials/utils/log/log.cpp22
-rw-r--r--yql/essentials/utils/multi_resource_lock.h6
-rw-r--r--yql/essentials/utils/oom_helper/inject.cpp4
-rw-r--r--yql/essentials/utils/signals/signals.cpp10
-rw-r--r--yql/essentials/utils/sys/linux_version.h2
-rw-r--r--yql/essentials/utils/url_builder.cpp18
-rw-r--r--yql/essentials/utils/url_builder.h4
-rw-r--r--yt/yt/client/api/chaos_client.h43
-rw-r--r--yt/yt/client/api/chaos_lease_base.cpp136
-rw-r--r--yt/yt/client/api/chaos_lease_base.h58
-rw-r--r--yt/yt/client/api/client.h2
-rw-r--r--yt/yt/client/api/delegating_client.h9
-rw-r--r--yt/yt/client/api/prerequisite.h2
-rw-r--r--yt/yt/client/api/prerequisite_client.h1
-rw-r--r--yt/yt/client/api/public.h2
-rw-r--r--yt/yt/client/api/rpc_proxy/api_service_proxy.h1
-rw-r--r--yt/yt/client/api/rpc_proxy/chaos_lease.cpp75
-rw-r--r--yt/yt/client/api/rpc_proxy/chaos_lease.h19
-rw-r--r--yt/yt/client/api/rpc_proxy/client_impl.cpp61
-rw-r--r--yt/yt/client/api/rpc_proxy/client_impl.h8
-rw-r--r--yt/yt/client/api/rpc_proxy/config.cpp2
-rw-r--r--yt/yt/client/api/rpc_proxy/config.h1
-rw-r--r--yt/yt/client/api/transaction.h2
-rw-r--r--yt/yt/client/chaos_client/public.h1
-rw-r--r--yt/yt/client/driver/chaos_commands.cpp20
-rw-r--r--yt/yt/client/driver/chaos_commands.h16
-rw-r--r--yt/yt/client/driver/driver.cpp1
-rw-r--r--yt/yt/client/federated/client.cpp2
-rw-r--r--yt/yt/client/hedging/hedging.cpp2
-rw-r--r--yt/yt/client/unittests/mock/client.h9
-rw-r--r--yt/yt/client/ya.make2
-rw-r--r--yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto11
-rw-r--r--yt/yt_proto/yt/client/chaos_client/proto/chaos_lease.proto10
-rw-r--r--yt/yt_proto/yt/client/ya.make1
154 files changed, 2258 insertions, 637 deletions
diff --git a/build/conf/java.conf b/build/conf/java.conf
index 552e16fed89..9135fa8020a 100644
--- a/build/conf/java.conf
+++ b/build/conf/java.conf
@@ -81,6 +81,10 @@ multimodule JAVA_PROGRAM {
module JAR_COMPILATION: _JAR_PROGRAM_COMPILATION {
.SEM=_BUILD_JAR_SEM
SET(MODULE_TYPE JAVA_PROGRAM)
+
+ when ($EXPORT_GRADLE == "yes") {
+ CONSUME_NON_MANAGEABLE_PEERS=yes
+ }
}
}
diff --git a/build/export_generators/ide-gradle/javac_flags.jinja b/build/export_generators/ide-gradle/javac_flags.jinja
index 642fd68a617..70c60db0a3b 100644
--- a/build/export_generators/ide-gradle/javac_flags.jinja
+++ b/build/export_generators/ide-gradle/javac_flags.jinja
@@ -25,9 +25,10 @@ tasks.{{ task }}.configure {
{%- if compiler_jvm_flags|length %}
options.isFork = true
options.forkOptions.jvmArgs = listOf(
-{%- for compiler_jvm_flag in compiler_jvm_flags -%}
-"{{ compiler_jvm_flag|replace("-J", "") }}"{% if not loop.last %}, {% endif -%}
-{%- endfor -%})
+{%- for compiler_jvm_flag in compiler_jvm_flags %}
+ "{{ compiler_jvm_flag|replace("-J", "") }}",
+{%- endfor %}
+ )
{% endif -%}
{%- if has_errorprone -%}
diff --git a/build/export_generators/ide-gradle/jvm_args.jinja b/build/export_generators/ide-gradle/jvm_args.jinja
index a37a9193710..7fe19a82ba1 100644
--- a/build/export_generators/ide-gradle/jvm_args.jinja
+++ b/build/export_generators/ide-gradle/jvm_args.jinja
@@ -1,20 +1,24 @@
{%- macro JvmArgs(jvm_args) -%}
-{%- if jvm_args|length %}
- jvmArgs = mutableListOf(
-{%- set jnis_args = jvm_args|select('startsWith', 'jnis=') %}
-{%- if jnis_args|length -%}
-{#- Increase heap, else happened java.lang.OutOfMemoryError #}
- "-Xmx2048m",
+{%- if jvm_args|length -%}
+{%- set jnis_args = jvm_args|select('startsWith', 'jnis=') -%}
+{%- set other_jvm_args = jvm_args|reject('startsWith', 'jnis=') -%}
+{%- if jnis_args|length %}
+ val library_path = listOf(
{%- for jnis_arg in jnis_args -%}
{%- set jnis = split(jnis_arg|replace('jnis=', ''), ',') -%}
-{#- Put paths to JNI libraries direct to JVM args -#}
{%- for jni in jnis -%}
{%- set path_and_name = rsplit(jni, "/", 2) %}
- "-Djava.library.path=$arcadia_root/{{ path_and_name[0] }}",
+ "$arcadia_root/{{ path_and_name[0] }}",
{%- endfor -%}
-{%- endfor -%}
+{%- endfor %}
+ ).joinToString(":")
+{% endif %}
+ jvmArgs = mutableListOf(
+{%- if jnis_args|length -%}
+{#- Increase heap, else happened java.lang.OutOfMemoryError #}
+ "-Xmx2048m",
+ "-Djava.library.path=$library_path",
{%- endif -%}
-{%- set other_jvm_args = jvm_args|reject('startsWith', 'jnis=') %}
{%- if other_jvm_args|length -%}
{%- for jvm_arg in other_jvm_args %}
"{{ jvm_arg }}",
diff --git a/build/export_generators/ide-gradle/source_sets.jinja b/build/export_generators/ide-gradle/source_sets.jinja
index ba2965d4c20..60793eb917e 100644
--- a/build/export_generators/ide-gradle/source_sets.jinja
+++ b/build/export_generators/ide-gradle/source_sets.jinja
@@ -14,9 +14,8 @@
#}
{{ module }}.srcDir({{ PatchRoots(dir) }})
{%- endif -%}
-{%- endmacro -%}
+{%- endmacro %}
-{#- empty string #}
sourceSets {
{%- set target_jar_source_set = target.jar_source_set|unique -%}
{%- set target_jar_resource_set = target.jar_resource_set|unique -%}
diff --git a/build/external_resources/gdb/resources.json b/build/external_resources/gdb/resources.json
index f7b21801fad..53472db6d38 100644
--- a/build/external_resources/gdb/resources.json
+++ b/build/external_resources/gdb/resources.json
@@ -7,10 +7,10 @@
"uri": "sbr:3833498694"
},
"linux-aarch64": {
- "uri": "sbr:8803622849"
+ "uri": "sbr:8989381149"
},
"linux-x86_64": {
- "uri": "sbr:8803613328"
+ "uri": "sbr:8989701781"
}
}
}
diff --git a/build/external_resources/ymake/public.resources.json b/build/external_resources/ymake/public.resources.json
index 1870648be65..d2a25322b5b 100644
--- a/build/external_resources/ymake/public.resources.json
+++ b/build/external_resources/ymake/public.resources.json
@@ -1,19 +1,19 @@
{
"by_platform": {
"darwin": {
- "uri": "sbr:8964594623"
+ "uri": "sbr:8972534424"
},
"darwin-arm64": {
- "uri": "sbr:8964594063"
+ "uri": "sbr:8972533338"
},
"linux": {
- "uri": "sbr:8964595237"
+ "uri": "sbr:8972536518"
},
"linux-aarch64": {
- "uri": "sbr:8964593480"
+ "uri": "sbr:8972533033"
},
"win32": {
- "uri": "sbr:8964594970"
+ "uri": "sbr:8972535583"
}
}
}
diff --git a/build/external_resources/ymake/resources.json b/build/external_resources/ymake/resources.json
index b63ec6ecb8e..bf5530609cb 100644
--- a/build/external_resources/ymake/resources.json
+++ b/build/external_resources/ymake/resources.json
@@ -1,19 +1,19 @@
{
"by_platform": {
"darwin": {
- "uri": "sbr:8964590476"
+ "uri": "sbr:8972532408"
},
"darwin-arm64": {
- "uri": "sbr:8964589998"
+ "uri": "sbr:8972531932"
},
"linux": {
- "uri": "sbr:8964591657"
+ "uri": "sbr:8972532988"
},
"linux-aarch64": {
- "uri": "sbr:8964589384"
+ "uri": "sbr:8972531727"
},
"win32": {
- "uri": "sbr:8964591278"
+ "uri": "sbr:8972532710"
}
}
}
diff --git a/build/mapping.conf.json b/build/mapping.conf.json
index 433c3be1e3c..feb56f83db2 100644
--- a/build/mapping.conf.json
+++ b/build/mapping.conf.json
@@ -561,6 +561,7 @@
"8865992733": "{registry_endpoint}/8865992733",
"8895767556": "{registry_endpoint}/8895767556",
"8944928850": "{registry_endpoint}/8944928850",
+ "8980584272": "{registry_endpoint}/8980584272",
"5486731632": "{registry_endpoint}/5486731632",
"5514350352": "{registry_endpoint}/5514350352",
"5514360398": "{registry_endpoint}/5514360398",
@@ -797,6 +798,7 @@
"8859746341": "{registry_endpoint}/8859746341",
"8926191672": "{registry_endpoint}/8926191672",
"8964594623": "{registry_endpoint}/8964594623",
+ "8972534424": "{registry_endpoint}/8972534424",
"5766171800": "{registry_endpoint}/5766171800",
"5805430761": "{registry_endpoint}/5805430761",
"5829025456": "{registry_endpoint}/5829025456",
@@ -884,6 +886,7 @@
"8859745406": "{registry_endpoint}/8859745406",
"8926191000": "{registry_endpoint}/8926191000",
"8964594063": "{registry_endpoint}/8964594063",
+ "8972533338": "{registry_endpoint}/8972533338",
"5766173070": "{registry_endpoint}/5766173070",
"5805432830": "{registry_endpoint}/5805432830",
"5829031598": "{registry_endpoint}/5829031598",
@@ -971,6 +974,7 @@
"8859748874": "{registry_endpoint}/8859748874",
"8926193753": "{registry_endpoint}/8926193753",
"8964595237": "{registry_endpoint}/8964595237",
+ "8972536518": "{registry_endpoint}/8972536518",
"5766171341": "{registry_endpoint}/5766171341",
"5805430188": "{registry_endpoint}/5805430188",
"5829023352": "{registry_endpoint}/5829023352",
@@ -1058,6 +1062,7 @@
"8859744568": "{registry_endpoint}/8859744568",
"8926190366": "{registry_endpoint}/8926190366",
"8964593480": "{registry_endpoint}/8964593480",
+ "8972533033": "{registry_endpoint}/8972533033",
"8270821739": "{registry_endpoint}/8270821739",
"8295446553": "{registry_endpoint}/8295446553",
"8326170338": "{registry_endpoint}/8326170338",
@@ -1075,6 +1080,7 @@
"8859747443": "{registry_endpoint}/8859747443",
"8926192834": "{registry_endpoint}/8926192834",
"8964594970": "{registry_endpoint}/8964594970",
+ "8972535583": "{registry_endpoint}/8972535583",
"5766172695": "{registry_endpoint}/5766172695",
"5805432230": "{registry_endpoint}/5805432230",
"5829029743": "{registry_endpoint}/5829029743",
@@ -1156,6 +1162,7 @@
"8784096409": "{registry_endpoint}/8784096409",
"6406540582": "{registry_endpoint}/6406540582",
"6447362348": "{registry_endpoint}/6447362348",
+ "8989381149": "{registry_endpoint}/8989381149",
"6133337898": "{registry_endpoint}/6133337898",
"8509776935": "{registry_endpoint}/8509776935",
"8803622849": "{registry_endpoint}/8803622849",
@@ -1165,6 +1172,7 @@
"8784094118": "{registry_endpoint}/8784094118",
"6406437536": "{registry_endpoint}/6406437536",
"6447316775": "{registry_endpoint}/6447316775",
+ "8989701781": "{registry_endpoint}/8989701781",
"6133419349": "{registry_endpoint}/6133419349",
"8509757921": "{registry_endpoint}/8509757921",
"8803613328": "{registry_endpoint}/8803613328",
@@ -2040,6 +2048,7 @@
"8865992733": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
"8895767556": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
"8944928850": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
+ "8980584272": "devtools/ya/test/programs/test_tool/bin/test_tool for linux",
"5486731632": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
"5514350352": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
"5514360398": "devtools/ya/test/programs/test_tool/bin3/test_tool3 for linux",
@@ -2276,6 +2285,7 @@
"8859746341": "devtools/ymake/bin/ymake for darwin",
"8926191672": "devtools/ymake/bin/ymake for darwin",
"8964594623": "devtools/ymake/bin/ymake for darwin",
+ "8972534424": "devtools/ymake/bin/ymake for darwin",
"5766171800": "devtools/ymake/bin/ymake for darwin-arm64",
"5805430761": "devtools/ymake/bin/ymake for darwin-arm64",
"5829025456": "devtools/ymake/bin/ymake for darwin-arm64",
@@ -2363,6 +2373,7 @@
"8859745406": "devtools/ymake/bin/ymake for darwin-arm64",
"8926191000": "devtools/ymake/bin/ymake for darwin-arm64",
"8964594063": "devtools/ymake/bin/ymake for darwin-arm64",
+ "8972533338": "devtools/ymake/bin/ymake for darwin-arm64",
"5766173070": "devtools/ymake/bin/ymake for linux",
"5805432830": "devtools/ymake/bin/ymake for linux",
"5829031598": "devtools/ymake/bin/ymake for linux",
@@ -2450,6 +2461,7 @@
"8859748874": "devtools/ymake/bin/ymake for linux",
"8926193753": "devtools/ymake/bin/ymake for linux",
"8964595237": "devtools/ymake/bin/ymake for linux",
+ "8972536518": "devtools/ymake/bin/ymake for linux",
"5766171341": "devtools/ymake/bin/ymake for linux-aarch64",
"5805430188": "devtools/ymake/bin/ymake for linux-aarch64",
"5829023352": "devtools/ymake/bin/ymake for linux-aarch64",
@@ -2537,6 +2549,7 @@
"8859744568": "devtools/ymake/bin/ymake for linux-aarch64",
"8926190366": "devtools/ymake/bin/ymake for linux-aarch64",
"8964593480": "devtools/ymake/bin/ymake for linux-aarch64",
+ "8972533033": "devtools/ymake/bin/ymake for linux-aarch64",
"8270821739": "devtools/ymake/bin/ymake for win32",
"8295446553": "devtools/ymake/bin/ymake for win32",
"8326170338": "devtools/ymake/bin/ymake for win32",
@@ -2554,6 +2567,7 @@
"8859747443": "devtools/ymake/bin/ymake for win32",
"8926192834": "devtools/ymake/bin/ymake for win32",
"8964594970": "devtools/ymake/bin/ymake for win32",
+ "8972535583": "devtools/ymake/bin/ymake for win32",
"5766172695": "devtools/ymake/bin/ymake for win32-clang-cl",
"5805432230": "devtools/ymake/bin/ymake for win32-clang-cl",
"5829029743": "devtools/ymake/bin/ymake for win32-clang-cl",
@@ -2635,6 +2649,7 @@
"8784096409": "gdb-14-linux-aarch64-6ea280bfa165555cc850c4ee3d49f07745e6f21b",
"6406540582": "gdb-14-linux-aarch64-9d91f66a1caff272af94e2fc97e690a18d910204",
"6447362348": "gdb-14-linux-aarch64-9db71d8b25a56ee316036c53fd941934a95831a3",
+ "8989381149": "gdb-14-linux-aarch64-a3d92401fcd70660cddbe51a1df09c7611122080",
"6133337898": "gdb-14-linux-aarch64-b1fa9be28bbf4ee845d6a39a049c7b60018a3695",
"8509776935": "gdb-14-linux-aarch64-b96bb13a4532bc0f19859cd0fd8590f36e4ac9f4",
"8803622849": "gdb-14-linux-aarch64-e086c237e91cadf80f94fc0b2c3268624f9e1058",
@@ -2644,6 +2659,7 @@
"8784094118": "gdb-14-linux-x86_64-6ea280bfa165555cc850c4ee3d49f07745e6f21b",
"6406437536": "gdb-14-linux-x86_64-9d91f66a1caff272af94e2fc97e690a18d910204",
"6447316775": "gdb-14-linux-x86_64-9db71d8b25a56ee316036c53fd941934a95831a3",
+ "8989701781": "gdb-14-linux-x86_64-a3d92401fcd70660cddbe51a1df09c7611122080",
"6133419349": "gdb-14-linux-x86_64-b1fa9be28bbf4ee845d6a39a049c7b60018a3695",
"8509757921": "gdb-14-linux-x86_64-b96bb13a4532bc0f19859cd0fd8590f36e4ac9f4",
"8803613328": "gdb-14-linux-x86_64-e086c237e91cadf80f94fc0b2c3268624f9e1058",
diff --git a/build/platform/test_tool/host.ya.make.inc b/build/platform/test_tool/host.ya.make.inc
index e0e7def8560..f617eedd3fa 100644
--- a/build/platform/test_tool/host.ya.make.inc
+++ b/build/platform/test_tool/host.ya.make.inc
@@ -1,12 +1,12 @@
IF (HOST_OS_DARWIN AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8944950171)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8980614277)
ELSEIF (HOST_OS_DARWIN AND HOST_ARCH_ARM64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8944944224)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8980612098)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8944959540)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8980618559)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_AARCH64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8944940103)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8980610092)
ELSEIF (HOST_OS_WINDOWS AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8944955524)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8980616449)
ENDIF()
diff --git a/build/platform/test_tool/host_os.ya.make.inc b/build/platform/test_tool/host_os.ya.make.inc
index 1744f9a6e44..b88a913e39e 100644
--- a/build/platform/test_tool/host_os.ya.make.inc
+++ b/build/platform/test_tool/host_os.ya.make.inc
@@ -1,12 +1,12 @@
IF (HOST_OS_DARWIN AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8944921953)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8980580464)
ELSEIF (HOST_OS_DARWIN AND HOST_ARCH_ARM64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8944917987)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8980578191)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8944928850)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8980584272)
ELSEIF (HOST_OS_LINUX AND HOST_ARCH_AARCH64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8944914253)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8980575843)
ELSEIF (HOST_OS_WINDOWS AND HOST_ARCH_X86_64)
- DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8944925436)
+ DECLARE_EXTERNAL_RESOURCE(TEST_TOOL_HOST sbr:8980582056)
ENDIF()
diff --git a/build/ymake.core.conf b/build/ymake.core.conf
index 8195ad0f667..d2b89fc87e5 100644
--- a/build/ymake.core.conf
+++ b/build/ymake.core.conf
@@ -2617,22 +2617,23 @@ macro _COPY_FILE_IMPL(TEXT[], AUTO_DST="", NOAUTO_DST="", OUTPUT_INCLUDES[], IND
.SEM=target_commands-ITEM && target_commands-macro copy_file && target_commands-args ${input:FILE} ${output:AUTO_DST} ${noauto;output:NOAUTO_DST}
}
-### @usage: COPY_FILE(File Destination [AUTO] [OUTPUT_INCLUDES Deps...])
+### @usage: COPY_FILE(File Destination [AUTO] [OUTPUT_INCLUDES...] [INDUCED_DEPS...] [TEXT])
###
### Copy file to build root. It is possible to change both location and the name.
###
### Parameters:
### - File - Source file name.
-### - Destination - Output file name.
+### - Dest - Output file name.
### - AUTO - Consider copied file for further processing automatically.
### - OUTPUT_INCLUDES output_includes... - Output file dependencies.
### - INDUCED_DEPS $VARs... - Dependencies for generated files. Unlike `OUTPUT_INCLUDES` these may target files further in processing chain.
### In order to do so VAR should be filled by PREPARE_INDUCED_DEPS macro, stating target files (by type)
### and set of dependencies
+### - TEXT - deprecated
###
### The file will be just copied if AUTO boolean parameter is not specified. You should explicitly
### mention it in SRCS under new name (or specify AUTO boolean parameter) for further processing.
-macro COPY_FILE(File, Destination, AUTO?"true":"false", OUTPUT_INCLUDES[], INDUCED_DEPS[], TEXT?"true":"false") {
+macro COPY_FILE(File, Dest, AUTO?"true":"false", OUTPUT_INCLUDES[], INDUCED_DEPS[], TEXT?"true":"false") {
# FIXME: the "TEXT" argument is effectively unused since _COPY_FILE_CONTEXT defaulting to TEXT
.CMD=$_COPY_FILE_CMD
.STRUCT_CMD=yes
@@ -2641,27 +2642,29 @@ macro COPY_FILE(File, Destination, AUTO?"true":"false", OUTPUT_INCLUDES[], INDUC
}
_COPY_FILE_CMD=$IF( \
${parse_bool:AUTO} \
- THEN $_COPY_FILE_IMPL(TEXT $File AUTO_DST $Destination OUTPUT_INCLUDES $OUTPUT_INCLUDES INDUCED_DEPS $INDUCED_DEPS) \
- ELSE $_COPY_FILE_IMPL(TEXT $File NOAUTO_DST $Destination OUTPUT_INCLUDES $OUTPUT_INCLUDES INDUCED_DEPS $INDUCED_DEPS) \
+ THEN $_COPY_FILE_IMPL(TEXT $File AUTO_DST $Dest OUTPUT_INCLUDES $OUTPUT_INCLUDES INDUCED_DEPS $INDUCED_DEPS) \
+ ELSE $_COPY_FILE_IMPL(TEXT $File NOAUTO_DST $Dest OUTPUT_INCLUDES $OUTPUT_INCLUDES INDUCED_DEPS $INDUCED_DEPS) \
)
_COPY_FILE_SEM=$IF( \
${parse_bool:AUTO} \
- THEN $_COPY_FILE_IMPL($File AUTO_DST $Destination) \
- ELSE $_COPY_FILE_IMPL($File NOAUTO_DST $Destination) \
+ THEN $_COPY_FILE_IMPL($File AUTO_DST $Dest) \
+ ELSE $_COPY_FILE_IMPL($File NOAUTO_DST $Dest) \
)
-### @usage: COPY_FILE_WITH_CONTEXT(FILE DEST [AUTO] [OUTPUT_INCLUDES DEPS...])
+### @usage: COPY_FILE_WITH_CONTEXT(File Dest [AUTO] [OUTPUT_INCLUDES...] [INDUCED_DEPS...])
###
### Copy file to build root the same way as it is done for COPY_FILE, but also
### propagates the context of the source file.
-macro COPY_FILE_WITH_CONTEXT(FILE, DEST, AUTO?"true":"false", OUTPUT_INCLUDES[], INDUCED_DEPS[]) {
+macro COPY_FILE_WITH_CONTEXT(File, Dest, AUTO?"true":"false", OUTPUT_INCLUDES[], INDUCED_DEPS[]) {
.CMD=$_COPY_FILE_WITH_CONTEXT_CMD
.STRUCT_CMD=yes
+ .SEM=$_COPY_FILE_SEM
+ .STRUCT_SEM=yes
}
_COPY_FILE_WITH_CONTEXT_CMD=$IF( \
${parse_bool:AUTO} \
- THEN $_COPY_FILE_IMPL($FILE AUTO_DST $DEST OUTPUT_INCLUDES_INP $FILE OUTPUT_INCLUDES $OUTPUT_INCLUDES INDUCED_DEPS $INDUCED_DEPS) \
- ELSE $_COPY_FILE_IMPL($FILE NOAUTO_DST $DEST OUTPUT_INCLUDES_INP $FILE OUTPUT_INCLUDES $OUTPUT_INCLUDES INDUCED_DEPS $INDUCED_DEPS) \
+ THEN $_COPY_FILE_IMPL($File AUTO_DST $Dest OUTPUT_INCLUDES_INP $File OUTPUT_INCLUDES $OUTPUT_INCLUDES INDUCED_DEPS $INDUCED_DEPS) \
+ ELSE $_COPY_FILE_IMPL($File NOAUTO_DST $Dest OUTPUT_INCLUDES_INP $File OUTPUT_INCLUDES $OUTPUT_INCLUDES INDUCED_DEPS $INDUCED_DEPS) \
)
### This is to join $ALL_RES_ and $EXT
diff --git a/contrib/libs/ftxui/.yandex_meta/__init__.py b/contrib/libs/ftxui/.yandex_meta/__init__.py
index 77b5f726f43..1ac64d6668f 100644
--- a/contrib/libs/ftxui/.yandex_meta/__init__.py
+++ b/contrib/libs/ftxui/.yandex_meta/__init__.py
@@ -1,5 +1,15 @@
+from devtools.yamaker.modules import Linkable, Switch
from devtools.yamaker.project import CMakeNinjaNixProject
+
+def post_install(self):
+ with self.yamakes["."] as ftxui:
+ ftxui.after(
+ "CFLAGS",
+ Switch({"OS_WINDOWS": Linkable(CFLAGS=["-DUNICODE", "-D_UNICODE"])}),
+ )
+
+
ftxui = CMakeNinjaNixProject(
owners=["segoon", "g:taxi-common"],
nixattr="ftxui",
@@ -9,4 +19,5 @@ ftxui = CMakeNinjaNixProject(
disable_includes=["emscripten.h"],
put_with={"ftxui-component": ["ftxui-dom", "ftxui-screen"]},
arcdir="contrib/libs/ftxui",
+ post_install=post_install,
)
diff --git a/contrib/libs/ftxui/.yandex_meta/override.nix b/contrib/libs/ftxui/.yandex_meta/override.nix
index c1bffb907ac..4fe68fcd8b5 100644
--- a/contrib/libs/ftxui/.yandex_meta/override.nix
+++ b/contrib/libs/ftxui/.yandex_meta/override.nix
@@ -14,5 +14,8 @@ pkgs: attrs: with pkgs; with attrs; rec {
"-DFTXUI_BUILD_EXAMPLES=OFF"
"-DFTXUI_BUILD_DOCS=OFF"
"-DFTXUI_BUILD_TESTS=OFF"
+ ] ++ lib.optionals (!stdenv.isLinux && !stdenv.isDarwin) [
+ "-DUNICODE=ON"
+ "-D_UNICODE=ON"
];
}
diff --git a/contrib/libs/ftxui/ya.make b/contrib/libs/ftxui/ya.make
index 19175672755..842e979a92d 100644
--- a/contrib/libs/ftxui/ya.make
+++ b/contrib/libs/ftxui/ya.make
@@ -22,6 +22,13 @@ NO_COMPILER_WARNINGS()
NO_UTIL()
+IF (OS_WINDOWS)
+ CFLAGS(
+ -DUNICODE
+ -D_UNICODE
+ )
+ENDIF()
+
SRCS(
src/ftxui/component/animation.cpp
src/ftxui/component/button.cpp
diff --git a/library/cpp/protobuf/json/json2proto.cpp b/library/cpp/protobuf/json/json2proto.cpp
index 823c471b967..a1d7e862ef0 100644
--- a/library/cpp/protobuf/json/json2proto.cpp
+++ b/library/cpp/protobuf/json/json2proto.cpp
@@ -7,6 +7,8 @@
#include <google/protobuf/util/time_util.h>
#include <google/protobuf/message.h>
#include <google/protobuf/descriptor.h>
+#include <google/protobuf/struct.pb.h>
+
#include <util/generic/hash.h>
#include <util/generic/maybe.h>
@@ -517,6 +519,57 @@ namespace NProtobufJson {
const google::protobuf::Descriptor* descriptor = proto.GetDescriptor();
Y_ASSERT(!!descriptor);
+
+ if (descriptor->well_known_type() == google::protobuf::Descriptor::WELLKNOWNTYPE_STRUCT) {
+ Y_ENSURE(json.IsMap(), "Failed to merge json to proto for message: " << descriptor->full_name() << ", expected json map.");
+ google::protobuf::Struct msg;
+ for (const auto& [key, value] : json.GetMap()) {
+ google::protobuf::Value valueMsg;
+ MergeJson2Proto(value, valueMsg, config);
+ (*msg.mutable_fields())[key] = std::move(valueMsg);
+ }
+ proto.GetReflection()->Swap(&proto, &msg);
+ return;
+ } else if (descriptor->well_known_type() == google::protobuf::Descriptor::WELLKNOWNTYPE_VALUE) {
+ google::protobuf::Value msg;
+ switch (json.GetType()) {
+ case NJson::JSON_UNDEFINED:
+ break;
+ case NJson::JSON_NULL:
+ msg.set_null_value({});
+ break;
+ case NJson::JSON_BOOLEAN:
+ msg.set_bool_value(json.GetBoolean());
+ break;
+ case NJson::JSON_INTEGER:
+ case NJson::JSON_DOUBLE:
+ case NJson::JSON_UINTEGER:
+ msg.set_number_value(json.GetDouble());
+ break;
+ case NJson::JSON_STRING:
+ msg.set_string_value(json.GetString());
+ break;
+ case NJson::JSON_MAP:
+ {
+ auto* structValue = msg.mutable_struct_value();
+ MergeJson2Proto(json, *structValue, config);
+ break;
+ }
+ case NJson::JSON_ARRAY:
+ {
+ auto* arrayValue = msg.mutable_list_value();
+ const auto& jsonArray = json.GetArray();
+ arrayValue->mutable_values()->Reserve(jsonArray.size());
+ for (const auto& item : jsonArray) {
+ MergeJson2Proto(item, *arrayValue->add_values(), config);
+ }
+ break;
+ }
+ }
+
+ proto.GetReflection()->Swap(&proto, &msg);
+ return;
+ }
Y_ENSURE(json.IsMap(), "Failed to merge json to proto for message: " << descriptor->full_name() << ", expected json map.");
for (int f = 0, endF = descriptor->field_count(); f < endF; ++f) {
diff --git a/library/cpp/protobuf/json/ut/json2proto_ut.cpp b/library/cpp/protobuf/json/ut/json2proto_ut.cpp
index 7b3e829868e..1172b2b8db6 100644
--- a/library/cpp/protobuf/json/ut/json2proto_ut.cpp
+++ b/library/cpp/protobuf/json/ut/json2proto_ut.cpp
@@ -2,6 +2,8 @@
#include "proto.h"
#include "proto2json.h"
+#include <google/protobuf/struct.pb.h>
+
#include <library/cpp/protobuf/json/ut/test.pb.h>
#include <library/cpp/json/json_value.h>
@@ -1186,4 +1188,81 @@ Y_UNIT_TEST(TestSimplifiedTimestamp) {
UNIT_ASSERT_EQUAL(NProtoInterop::CastFromProto(simpleTimestamp.GetTimestamp()), TInstant::ParseIso8601("2014-08-26T15:52:15Z"));
} // TestSimplifiedTimestamp
+Y_UNIT_TEST(TestValue) {
+ {
+ NJson::TJsonValue json = 100.0;
+ google::protobuf::Value value;
+ NProtobufJson::Json2Proto(json, value);
+ UNIT_ASSERT(value.has_number_value());
+ UNIT_ASSERT_EQUAL(value.number_value(), 100.0);
+ }
+ {
+ NJson::TJsonValue json = 100LL;
+ google::protobuf::Value value;
+ NProtobufJson::Json2Proto(json, value);
+ UNIT_ASSERT(value.has_number_value());
+ UNIT_ASSERT_EQUAL(value.number_value(), 100.0);
+ }
+ {
+ NJson::TJsonValue json = 100ULL;
+ google::protobuf::Value value;
+ NProtobufJson::Json2Proto(json, value);
+ UNIT_ASSERT(value.has_number_value());
+ UNIT_ASSERT_EQUAL(value.number_value(), 100.0);
+ }
+ {
+ NJson::TJsonValue json = "TestString";
+ google::protobuf::Value value;
+ NProtobufJson::Json2Proto(json, value);
+ UNIT_ASSERT(value.has_string_value());
+ UNIT_ASSERT_EQUAL(value.string_value(), "TestString");
+ }
+ {
+ NJson::TJsonValue json;
+ json.AppendValue("TestString");
+ json.AppendValue(2);
+ google::protobuf::Value value;
+ NProtobufJson::Json2Proto(json, value);
+ UNIT_ASSERT(value.has_list_value());
+ const auto& list = value.list_value().values();
+ UNIT_ASSERT_EQUAL(list.size(), 2);
+ UNIT_ASSERT(list.Get(0).has_string_value());
+ UNIT_ASSERT_EQUAL(list.Get(0).string_value(), "TestString");
+ UNIT_ASSERT(list.Get(1).has_number_value());
+ UNIT_ASSERT_EQUAL(list.Get(1).number_value(), 2.0);
+ }
+ {
+ NJson::TJsonValue json;
+ json["str"] = "TestString";
+ json["int"] = 2;
+ google::protobuf::Value value;
+ NProtobufJson::Json2Proto(json, value);
+ UNIT_ASSERT(value.has_struct_value());
+ const auto& fields = value.struct_value().fields();
+ UNIT_ASSERT_EQUAL(fields.size(), 2);
+
+ UNIT_ASSERT(fields.at("str").has_string_value());
+ UNIT_ASSERT_EQUAL(fields.at("str").string_value(), "TestString");
+
+ UNIT_ASSERT(fields.at("int").has_number_value());
+ UNIT_ASSERT_EQUAL(fields.at("int").number_value(), 2.0);
+ }
+} // TestValue
+
+Y_UNIT_TEST(TestStruct) {
+ NJson::TJsonValue json;
+ json["str"] = "TestString";
+ json["int"] = 2;
+ google::protobuf::Struct structProto;
+ NProtobufJson::Json2Proto(json, structProto);
+
+ const auto& fields = structProto.fields();
+ UNIT_ASSERT_EQUAL(fields.size(), 2);
+ UNIT_ASSERT(fields.at("str").has_string_value());
+ UNIT_ASSERT_EQUAL(fields.at("str").string_value(), "TestString");
+
+ UNIT_ASSERT(fields.at("int").has_number_value());
+ UNIT_ASSERT_EQUAL(fields.at("int").number_value(), 2.0);
+} // TestStruct
+
} // TJson2ProtoTest
diff --git a/ya b/ya
index 2fa6c0a8a55..8ff164d8321 100755
--- a/ya
+++ b/ya
@@ -39,33 +39,33 @@ REGISTRY_ENDPOINT = os.environ.get("YA_REGISTRY_ENDPOINT", "https://devtools-reg
PLATFORM_MAP = {
"data": {
"win32": {
- "md5": "6930b764b10d4ea8d8e1fdcc86fe81af",
+ "md5": "9534abf2236bf986a73695c6a6020d9b",
"urls": [
- f"{REGISTRY_ENDPOINT}/8945021042"
+ f"{REGISTRY_ENDPOINT}/8980613788"
]
},
"darwin": {
- "md5": "f36a717cf732b6f3be1ea5e98c96c08a",
+ "md5": "a303402147dc93d600c4c23e54ac2313",
"urls": [
- f"{REGISTRY_ENDPOINT}/8945018014"
+ f"{REGISTRY_ENDPOINT}/8980611775"
]
},
"darwin-arm64": {
- "md5": "20710b2a45d8ac8bcc78a9310dd08511",
+ "md5": "bf51ba63f8ded4b9b19b841869f24ea7",
"urls": [
- f"{REGISTRY_ENDPOINT}/8945012760"
+ f"{REGISTRY_ENDPOINT}/8980609753"
]
},
"linux-aarch64": {
- "md5": "a7baedd28b02efb64a1c1101b249f553",
+ "md5": "74e1dd7dbb2639d9a4590f91da3cbac7",
"urls": [
- f"{REGISTRY_ENDPOINT}/8945008840"
+ f"{REGISTRY_ENDPOINT}/8980607719"
]
},
"linux": {
- "md5": "3ef5d52fee076763d64a978df3e2f54d",
+ "md5": "2bb10d9f76f496f5982601a38c61856e",
"urls": [
- f"{REGISTRY_ENDPOINT}/8945024867"
+ f"{REGISTRY_ENDPOINT}/8980615911"
]
}
}
diff --git a/ydb/ci/rightlib.txt b/ydb/ci/rightlib.txt
index 852d3419e50..d7ce019752e 100644
--- a/ydb/ci/rightlib.txt
+++ b/ydb/ci/rightlib.txt
@@ -1 +1 @@
-1496d6ee1dfd8d449a3f9de4703f86dd5a1243f5
+eb5cfac23dd911355748ad88375812f00b50958e
diff --git a/yql/essentials/cfg/tests/gateways.conf b/yql/essentials/cfg/tests/gateways.conf
index 49af78d8793..920e10d5e1f 100644
--- a/yql/essentials/cfg/tests/gateways.conf
+++ b/yql/essentials/cfg/tests/gateways.conf
@@ -82,6 +82,11 @@ Yt {
Value: "10M"
}
+ DefaultSettings {
+ Name: "UseIntermediateStreams"
+ Value: "true"
+ }
+
RemoteFilePatterns {
Pattern: "yt://([a-zA-Z0-9\\-_]+)/([^&@?]+)$"
Cluster: "$1"
diff --git a/yql/essentials/core/facade/yql_facade.cpp b/yql/essentials/core/facade/yql_facade.cpp
index 2543dcf2d62..e06135256fe 100644
--- a/yql/essentials/core/facade/yql_facade.cpp
+++ b/yql/essentials/core/facade/yql_facade.cpp
@@ -1989,6 +1989,7 @@ TTypeAnnotationContextPtr TProgram::BuildTypeAnnotationContext(const TString& us
auto typeAnnotationContext = MakeIntrusive<TTypeAnnotationContext>();
typeAnnotationContext->LangVer = LangVer_;
+ typeAnnotationContext->UseTypeDiffForConvertToError = true;
typeAnnotationContext->UserDataStorage = UserDataStorage_;
typeAnnotationContext->Credentials = Credentials_;
typeAnnotationContext->Modules = Modules_;
diff --git a/yql/essentials/core/type_ann/type_ann_blocks.cpp b/yql/essentials/core/type_ann/type_ann_blocks.cpp
index c988284b2bc..6352feca919 100644
--- a/yql/essentials/core/type_ann/type_ann_blocks.cpp
+++ b/yql/essentials/core/type_ann/type_ann_blocks.cpp
@@ -968,7 +968,7 @@ IGraphTransformer::TStatus ListFromBlocksWrapper(const TExprNode::TPtr& input, T
return IGraphTransformer::TStatus::Ok;
}
-IGraphTransformer::TStatus WideSkipTakeBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+IGraphTransformer::TStatus WideSkipTakeBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 2U, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -980,7 +980,7 @@ IGraphTransformer::TStatus WideSkipTakeBlocksWrapper(const TExprNode::TPtr& inpu
output = input;
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, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Can not convert argument to Uint64"));
return IGraphTransformer::TStatus::Error;
@@ -994,7 +994,7 @@ IGraphTransformer::TStatus WideSkipTakeBlocksWrapper(const TExprNode::TPtr& inpu
return IGraphTransformer::TStatus::Ok;
}
-IGraphTransformer::TStatus WideTopBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+IGraphTransformer::TStatus WideTopBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 3U, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1006,7 +1006,7 @@ IGraphTransformer::TStatus WideTopBlocksWrapper(const TExprNode::TPtr& input, TE
output = input;
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, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Can not convert argument to Uint64"));
return IGraphTransformer::TStatus::Error;
diff --git a/yql/essentials/core/type_ann/type_ann_blocks.h b/yql/essentials/core/type_ann/type_ann_blocks.h
index 223758ef7fc..4d417ad4ed4 100644
--- a/yql/essentials/core/type_ann/type_ann_blocks.h
+++ b/yql/essentials/core/type_ann/type_ann_blocks.h
@@ -31,8 +31,8 @@ namespace NTypeAnnImpl {
IGraphTransformer::TStatus ListToBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
IGraphTransformer::TStatus WideFromBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ListFromBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus WideSkipTakeBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus WideTopBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus WideSkipTakeBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
+ IGraphTransformer::TStatus WideTopBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
IGraphTransformer::TStatus WideSortBlocksWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus BlockPgOpWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus BlockPgCallWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
diff --git a/yql/essentials/core/type_ann/type_ann_core.cpp b/yql/essentials/core/type_ann/type_ann_core.cpp
index 166307cdf68..75043a88ede 100644
--- a/yql/essentials/core/type_ann/type_ann_core.cpp
+++ b/yql/essentials/core/type_ann/type_ann_core.cpp
@@ -2161,7 +2161,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus MinMaxWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MinMaxWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2184,7 +2184,8 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (const auto status = ConvertChildrenToType(input, commonItemType, ctx.Expr); status != IGraphTransformer::TStatus::Ok) {
+ if (const auto status = ConvertChildrenToType(input, commonItemType, ctx.Expr, ctx.Types.UseTypeDiffForConvertToError);
+ status != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -3050,7 +3051,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ShiftWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ShiftWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3074,7 +3075,7 @@ namespace NTypeAnnImpl {
}
const auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint8);
- const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
+ const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), "Shift count must be Uint8"));
return IGraphTransformer::TStatus::Error;
@@ -3214,7 +3215,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus SubstringWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus SubstringWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3249,7 +3250,7 @@ namespace NTypeAnnImpl {
if (kindOne == ETypeAnnotationKind::Optional || kindOne == ETypeAnnotationKind::Null) {
expectedTypeOne = ctx.Expr.MakeType<TOptionalExprType>(expectedTypeOne);
}
- const auto convertStatus1 = TryConvertTo(input->ChildRef(1), *expectedTypeOne, ctx.Expr);
+ const auto convertStatus1 = TryConvertTo(input->ChildRef(1), *expectedTypeOne, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus1.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -3260,7 +3261,7 @@ namespace NTypeAnnImpl {
if (kindTwo == ETypeAnnotationKind::Optional || kindTwo == ETypeAnnotationKind::Null) {
expectedTypeTwo = ctx.Expr.MakeType<TOptionalExprType>(expectedTypeTwo);
}
- const auto convertStatus2 = TryConvertTo(input->ChildRef(2), *expectedTypeTwo, ctx.Expr);
+ const auto convertStatus2 = TryConvertTo(input->ChildRef(2), *expectedTypeTwo, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus2.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(2)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -3275,7 +3276,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus FindWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus FindWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3301,7 +3302,8 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Error;
}
- if (const auto convertStatus = TryConvertTo(input->ChildRef(1), *type, ctx.Expr); convertStatus.Level != IGraphTransformer::TStatus::Ok) {
+ if (const auto convertStatus = TryConvertTo(input->ChildRef(1), *type, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
+ convertStatus.Level != IGraphTransformer::TStatus::Ok) {
return convertStatus;
}
@@ -3310,7 +3312,8 @@ namespace NTypeAnnImpl {
expectedType = ctx.Expr.MakeType<TOptionalExprType>(expectedType);
}
- if (const auto convertStatus = TryConvertTo(input->ChildRef(2), *expectedType, ctx.Expr); convertStatus.Level != IGraphTransformer::TStatus::Ok) {
+ if (const auto convertStatus = TryConvertTo(input->ChildRef(2), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
+ convertStatus.Level != IGraphTransformer::TStatus::Ok) {
return convertStatus;
}
@@ -3364,7 +3367,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ByteAtWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ByteAtWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3399,7 +3402,7 @@ namespace NTypeAnnImpl {
}
auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32);
- auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -3432,7 +3435,7 @@ namespace NTypeAnnImpl {
}
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, TExtContext& ctx) {
if (input->ChildrenSize() == 0) {
output = ctx.Expr.NewCallable(input->Pos(), "EmptyList", {});
return IGraphTransformer::TStatus::Repeat;
@@ -3456,7 +3459,8 @@ namespace NTypeAnnImpl {
output = ctx.Expr.RenameNode(*input, "AsList");
return IGraphTransformer::TStatus::Repeat;
} else if (const auto commonItemType = CommonTypeForChildren(*input, ctx.Expr, warn)) {
- if (const auto status = ConvertChildrenToType(input, commonItemType, ctx.Expr); status != IGraphTransformer::TStatus::Ok)
+ if (const auto status = ConvertChildrenToType(input, commonItemType, ctx.Expr, ctx.Types.UseTypeDiffForConvertToError);
+ status != IGraphTransformer::TStatus::Ok)
return status;
} else {
return IGraphTransformer::TStatus::Error;
@@ -5394,7 +5398,7 @@ 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, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -5442,7 +5446,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, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
return IGraphTransformer::TStatus::Error;
} else if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
@@ -5915,7 +5919,7 @@ 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, TExtContext& ctx) {
if (input->ChildrenSize() == 0) {
output = ctx.Expr.NewCallable(input->Pos(), "EmptyDict", {});
return IGraphTransformer::TStatus::Repeat;
@@ -5951,7 +5955,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
output = ctx.Expr.RenameNode(*input, IsSet ? "AsSet" : "AsDict");
return IGraphTransformer::TStatus::Repeat;
} else if (const auto commonType = CommonTypeForChildren(*input, ctx.Expr, warn)) {
- if (const auto status = ConvertChildrenToType(input, commonType, ctx.Expr); status != IGraphTransformer::TStatus::Ok)
+ if (const auto status = ConvertChildrenToType(input, commonType, ctx.Expr, ctx.Types.UseTypeDiffForConvertToError);
+ status != IGraphTransformer::TStatus::Ok)
return status;
if (warn) {
@@ -5973,7 +5978,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus DictFromKeysWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus DictFromKeysWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -5998,7 +6003,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
for (size_t i = 0; i < keysListNode->ChildrenSize(); ++i) {
newChildren.push_back(keysListNode->ChildPtr(i));
auto& childRef = newChildren.back();
- auto status = TryConvertTo(childRef, *keyType, ctx.Expr);
+ auto status = TryConvertTo(childRef, *keyType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
totalStatus = totalStatus.Combine(status);
if (status.Level == IGraphTransformer::TStatus::Error) {
return status;
@@ -6020,7 +6025,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
template <bool IsStrict>
- IGraphTransformer::TStatus IfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus IfWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6051,7 +6056,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
} else if (const auto commonType = CommonType<false>(input->Pos(), thenType, elseType, ctx.Expr)) {
- if (const auto status = TryConvertTo(input->ChildRef(1), *commonType, ctx.Expr).Combine(TryConvertTo(input->TailRef(), *commonType, ctx.Expr)); status != IGraphTransformer::TStatus::Ok)
+ if (const auto status = TryConvertTo(input->ChildRef(1), *commonType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError)
+ .Combine(TryConvertTo(input->TailRef(), *commonType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError));
+ status != IGraphTransformer::TStatus::Ok)
return status;
input->SetTypeAnn(commonType);
@@ -7809,7 +7816,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, {}, ctx.Types.UseTypeDiffForConvertToError);
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 "
@@ -8580,14 +8587,14 @@ 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, TExtContext& ctx) {
Y_UNUSED(output);
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, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -8818,7 +8825,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus DynamicVariantWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus DynamicVariantWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -8845,7 +8852,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
EDataSlot::Uint32 :
EDataSlot::Utf8));
- auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -8879,7 +8886,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
}
- convertStatus = TryConvertTo(input->ChildRef(0), *firstType, ctx.Expr);
+ convertStatus = TryConvertTo(input->ChildRef(0), *firstType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(0)->Pos()),
TStringBuilder() << "Mismatch item type, expected: " << *firstType << ", got: " << *input->Child(0)->GetTypeAnn()));
@@ -10541,7 +10548,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
if (!EnsureQueueResource(resourceArg, expectedValueType, ctx)) {
return IGraphTransformer::TStatus::Error;
}
- auto convertStatus = TryConvertTo(valueArg, *expectedValueType, ctx.Expr);
+ auto convertStatus = TryConvertTo(valueArg, *expectedValueType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
return convertStatus;
}
@@ -10577,7 +10584,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Error;
}
auto expectedIndexType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- auto convertStatus = TryConvertTo(indexArg, *expectedIndexType, ctx.Expr);
+ auto convertStatus = TryConvertTo(indexArg, *expectedIndexType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
return convertStatus;
}
@@ -10602,8 +10609,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
auto expectedIndexType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- auto convertStatus = TryConvertTo(beginArg, *expectedIndexType, ctx.Expr);
- convertStatus = convertStatus.Combine(TryConvertTo(endArg, *expectedIndexType, ctx.Expr));
+ auto convertStatus = TryConvertTo(beginArg, *expectedIndexType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
+ convertStatus = convertStatus.Combine(TryConvertTo(endArg, *expectedIndexType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError));
if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
return convertStatus;
}
@@ -10737,7 +10744,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
}
}
- IGraphTransformer::TStatus WeakFieldWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus WeakFieldWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureMinArgsCount(*input, 3, ctx.Expr) || !EnsureMaxArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -10765,7 +10772,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
const bool isDefault = input->ChildrenSize() == 4;
if (isDefault) {
- auto convertStatus = TryConvertTo(input->ChildRef(3), *targetTypeExpr, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(3), *targetTypeExpr, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), TStringBuilder() <<
"Default value not correspond weak field type: " << targetType));
@@ -10954,7 +10961,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Repeat;
}
- IGraphTransformer::TStatus TryWeakMemberFromDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TryWeakMemberFromDictWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -10966,7 +10973,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
const EDataSlot payloadStr = isYsonPayload ? EDataSlot::Yson : EDataSlot::String;
auto expectedType = ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDictExprType>(
ctx.Expr.MakeType<TDataExprType>(EDataSlot::String), ctx.Expr.MakeType<TDataExprType>(payloadStr)));
- auto convertStatus = TryConvertTo(dictNodeRef, *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(dictNodeRef, *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level != IGraphTransformer::TStatus::Ok) {
return convertStatus;
}
@@ -11395,7 +11402,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus TimezoneIdWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TimezoneIdWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -11412,7 +11419,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
// name
} else {
const TTypeAnnotationNode* expectedType = isOptional ? optUi16Type : ui16Type;
- auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -11430,7 +11437,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus TimezoneNameWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TimezoneNameWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -11447,7 +11454,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
expectedType = ctx.Expr.MakeType<TOptionalExprType>(expectedType);
}
- auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -11461,7 +11468,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus AddTimezoneWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus AddTimezoneWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -11487,7 +11494,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
const TTypeAnnotationNode* ui16Type = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint16);
const TTypeAnnotationNode* optUi16Type = ctx.Expr.MakeType<TOptionalExprType>(ui16Type);
const TTypeAnnotationNode* expectedType = isOptional2 ? optUi16Type : ui16Type;
- auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -12489,10 +12496,10 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions[RightName] = &RightWrapper;
Functions[ConsName] = &ConsWrapper;
Functions["DataSink"] = &DataSinkWrapper;
- Functions["Filter"] = &FilterWrapper;
- Functions["OrderedFilter"] = &FilterWrapper;
- Functions["TakeWhile"] = &FilterWrapper;
- Functions["SkipWhile"] = &FilterWrapper;
+ ExtFunctions["Filter"] = &FilterWrapper;
+ ExtFunctions["OrderedFilter"] = &FilterWrapper;
+ ExtFunctions["TakeWhile"] = &FilterWrapper;
+ ExtFunctions["SkipWhile"] = &FilterWrapper;
Functions["TakeWhileInclusive"] = &InclusiveFilterWrapper<false>;
Functions["SkipWhileInclusive"] = &InclusiveFilterWrapper<true>;
Functions["Member"] = &MemberWrapper;
@@ -12561,8 +12568,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["BitAnd"] = &BitOpsWrapper<2>;
Functions["BitOr"] = &BitOpsWrapper<2>;
Functions["BitXor"] = &BitOpsWrapper<2>;
- Functions["Min"] = &MinMaxWrapper;
- Functions["Max"] = &MinMaxWrapper;
+ ExtFunctions["Min"] = &MinMaxWrapper;
+ ExtFunctions["Max"] = &MinMaxWrapper;
Functions["AggrEquals"] = &AggrCompareWrapper<true, false>;
Functions["AggrNotEquals"] = &AggrCompareWrapper<false, false>;
Functions["AggrLess"] = &AggrCompareWrapper<false, true>;
@@ -12574,28 +12581,28 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["IsNotDistinctFrom"] = &DistinctFromWrapper;
Functions["IsDistinctFrom"] = &DistinctFromWrapper;;
Functions["Abs"] = &AbsWrapper;
- Functions["ShiftLeft"] = &ShiftWrapper;
- Functions["RotLeft"] = &ShiftWrapper;
- Functions["ShiftRight"] = &ShiftWrapper;
- Functions["RotRight"] = &ShiftWrapper;
+ ExtFunctions["ShiftLeft"] = &ShiftWrapper;
+ ExtFunctions["RotLeft"] = &ShiftWrapper;
+ ExtFunctions["ShiftRight"] = &ShiftWrapper;
+ ExtFunctions["RotRight"] = &ShiftWrapper;
Functions[SyncName] = &SyncWrapper;
Functions["WithWorld"] = &WithWorldWrapper;
Functions["Concat"] = &ConcatWrapper;
Functions["AggrConcat"] = &AggrConcatWrapper;
- Functions["Substring"] = &SubstringWrapper;
- Functions["Find"] = &FindWrapper;
- Functions["RFind"] = &FindWrapper;
+ ExtFunctions["Substring"] = &SubstringWrapper;
+ ExtFunctions["Find"] = &FindWrapper;
+ ExtFunctions["RFind"] = &FindWrapper;
Functions["StartsWith"] = &WithWrapper;
Functions["StartsWithIgnoreCase"] = &WithWrapper;
Functions["EndsWith"] = &WithWrapper;
Functions["EndsWithIgnoreCase"] = &WithWrapper;
Functions["StringContains"] = &WithWrapper;
Functions["StringContainsIgnoreCase"] = &WithWrapper;
- Functions["ByteAt"] = &ByteAtWrapper;
+ ExtFunctions["ByteAt"] = &ByteAtWrapper;
Functions["ListIf"] = &ListIfWrapper;
- Functions["AsList"] = &AsListWrapper<false>;
- Functions["AsListMayWarn"] = &AsListWrapper<false>;
- Functions["AsListStrict"] = &AsListWrapper<true>;
+ ExtFunctions["AsList"] = &AsListWrapper<false>;
+ ExtFunctions["AsListMayWarn"] = &AsListWrapper<false>;
+ ExtFunctions["AsListStrict"] = &AsListWrapper<true>;
Functions["ToList"] = &ToListWrapper;
Functions["ToOptional"] = &ToOptionalWrapper;
Functions["Iterable"] = &IterableWrapper;
@@ -12643,14 +12650,14 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["ToSequence"] = &ToSequenceWrapper;
Functions["Collect"] = &CollectWrapper;
Functions["LazyList"] = &LazyListWrapper;
- Functions["ListFromRange"] = &ListFromRangeWrapper;
- Functions["Replicate"] = &ReplicateWrapper;
+ ExtFunctions["ListFromRange"] = &ListFromRangeWrapper;
+ ExtFunctions["Replicate"] = &ReplicateWrapper;
Functions["Switch"] = &SwitchWrapper;
Functions["Chopper"] = &ChopperWrapper;
Functions["HasItems"] = &HasItemsWrapper;
- Functions["Append"] = &AppendWrapper;
- Functions["Insert"] = &AppendWrapper;
- Functions["Prepend"] = &PrependWrapper;
+ ExtFunctions["Append"] = &AppendWrapper;
+ ExtFunctions["Insert"] = &AppendWrapper;
+ ExtFunctions["Prepend"] = &PrependWrapper;
Functions["Extend"] = &ExtendWrapper;
Functions["OrderedExtend"] = &ExtendWrapper;
Functions["Merge"] = &ExtendWrapper;
@@ -12659,8 +12666,8 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["UnionAll"] = &UnionAllWrapper;
Functions["UnionMerge"] = &UnionAllWrapper;
Functions["Union"] = &UnionAllWrapper;
- Functions["ListExtend"] = &ListExtendWrapper<false>;
- Functions["ListExtendStrict"] = &ListExtendWrapper<true>;
+ ExtFunctions["ListExtend"] = &ListExtendWrapper<false>;
+ ExtFunctions["ListExtendStrict"] = &ListExtendWrapper<true>;
Functions["ListUnionAll"] = &ListUnionAllWrapper;
Functions["ListZip"] = &ListZipWrapper;
Functions["ListZipAll"] = &ListZipAllWrapper;
@@ -12676,9 +12683,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["AssumeStrict"] = &AssumeStrictWrapper;
Functions["AssumeNonStrict"] = &AssumeStrictWrapper;
Functions["EnsureStrict"] = &EnsureStrictWrapper;
- Functions["Top"] = &TopWrapper;
- Functions["TopSort"] = &TopWrapper;
- Functions["KeepTop"] = &KeepTopWrapper;
+ ExtFunctions["Top"] = &TopWrapper;
+ ExtFunctions["TopSort"] = &TopWrapper;
+ ExtFunctions["KeepTop"] = &KeepTopWrapper;
Functions["Unordered"] = &UnorderedWrapper;
Functions["UnorderedSubquery"] = &UnorderedWrapper;
Functions["SortTraits"] = &SortTraitsWrapper;
@@ -12711,9 +12718,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["PartitionByKey"] = &PartitionByKeyWrapper;
Functions["PartitionsByKeys"] = &PartitionsByKeysWrapper;
Functions["Reverse"] = &ReverseWrapper;
- Functions["Skip"] = &TakeWrapper;
- Functions["Take"] = &TakeWrapper;
- Functions["Limit"] = &TakeWrapper;
+ ExtFunctions["Skip"] = &TakeWrapperEx;
+ ExtFunctions["Take"] = &TakeWrapperEx;
+ ExtFunctions["Limit"] = &TakeWrapperEx;
Functions["Fold"] = &FoldWrapper;
Functions["Fold1"] = &Fold1Wrapper;
Functions["Condense"] = &CondenseWrapper;
@@ -12723,7 +12730,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["Discard"] = &DiscardWrapper;
Functions["Zip"] = &ZipWrapper;
Functions["ZipAll"] = &ZipAllWrapper;
- Functions["Enumerate"] = &EnumerateWrapper;
+ ExtFunctions["Enumerate"] = &EnumerateWrapper;
Functions["GenericType"] = &TypeWrapper<ETypeAnnotationKind::Generic>;
Functions["ResourceType"] = &TypeWrapper<ETypeAnnotationKind::Resource>;
Functions["ErrorType"] = &TypeWrapper<ETypeAnnotationKind::Error>;
@@ -12744,9 +12751,9 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["List"] = &ListWrapper;
Functions["DictType"] = &TypeWrapper<ETypeAnnotationKind::Dict>;
Functions["Dict"] = &DictWrapper;
- Functions["Variant"] = &VariantWrapper;
+ ExtFunctions["Variant"] = &VariantWrapper;
Functions["Enum"] = &EnumWrapper;
- Functions["DynamicVariant"] = &DynamicVariantWrapper;
+ ExtFunctions["DynamicVariant"] = &DynamicVariantWrapper;
Functions["AsVariant"] = &AsVariantWrapper;
Functions["AsEnum"] = &AsEnumWrapper;
Functions["Contains"] = &ContainsLookupWrapper<true>;
@@ -12757,17 +12764,17 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["DictPayloads"] = &DictItemsWrapper<EDictItems::Payloads>;
Functions["AsStruct"] = &AsStructWrapper;
Functions["AsStructUnordered"] = &AsStructWrapper;
- Functions["AsDict"] = &AsDictWrapper<false, false>;
- Functions["AsDictMayWarn"] = &AsDictWrapper<false, false>;
- Functions["AsDictStrict"] = &AsDictWrapper<true, false>;
- Functions["AsSet"] = &AsDictWrapper<false, true>;
- Functions["AsSetMayWarn"] = &AsDictWrapper<false, true>;
- Functions["AsSetStrict"] = &AsDictWrapper<true, true>;
- Functions["DictFromKeys"] = &DictFromKeysWrapper;
+ ExtFunctions["AsDict"] = &AsDictWrapper<false, false>;
+ ExtFunctions["AsDictMayWarn"] = &AsDictWrapper<false, false>;
+ ExtFunctions["AsDictStrict"] = &AsDictWrapper<true, false>;
+ ExtFunctions["AsSet"] = &AsDictWrapper<false, true>;
+ ExtFunctions["AsSetMayWarn"] = &AsDictWrapper<false, true>;
+ ExtFunctions["AsSetStrict"] = &AsDictWrapper<true, true>;
+ ExtFunctions["DictFromKeys"] = &DictFromKeysWrapper;
Functions["Uniq"] = &UniqWrapper;
Functions["UniqStable"] = &UniqWrapper;
- Functions["If"] = &IfWrapper<false>;
- Functions["IfStrict"] = &IfWrapper<true>;
+ ExtFunctions["If"] = &IfWrapper<false>;
+ ExtFunctions["IfStrict"] = &IfWrapper<true>;
Functions[IfName] = &IfWorldWrapper;
Functions[ForName] = &ForWorldWrapper;
Functions["IfPresent"] = &IfPresentWrapper;
@@ -12836,7 +12843,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["CallableArgumentType"] = &TypeArgWrapper<ETypeArgument::CallableArgument>;
Functions["CombineByKey"] = &CombineByKeyWrapper;
Functions["FinalizeByKey"] = &CombineByKeyWrapper;
- Functions["NewMTRand"] = &NewMTRandWrapper;
+ ExtFunctions["NewMTRand"] = &NewMTRandWrapper;
Functions["NextMTRand"] = &NextMTRandWrapper;
Functions["FormatType"] = &FormatTypeWrapper;
Functions["FormatTypeDiff"] = &FormatTypeDiffWrapper;
@@ -12859,14 +12866,14 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["CalcOverWindow"] = &CalcOverWindowWrapper;
Functions["CalcOverSessionWindow"] = &CalcOverWindowWrapper;
Functions["CalcOverWindowGroup"] = &CalcOverWindowGroupWrapper;
- Functions["Lag"] = &WinLeadLagWrapper;
- Functions["Lead"] = &WinLeadLagWrapper;
+ ExtFunctions["Lag"] = &WinLeadLagWrapper;
+ ExtFunctions["Lead"] = &WinLeadLagWrapper;
Functions["RowNumber"] = &WinRowNumberWrapper;
Functions["Rank"] = &WinRankWrapper;
Functions["DenseRank"] = &WinRankWrapper;
Functions["PercentRank"] = &WinRankWrapper;
Functions["CumeDist"] = &WinCumeDistWrapper;
- Functions["NTile"] = &WinNTileWrapper;
+ ExtFunctions["NTile"] = &WinNTileWrapper;
Functions["Ascending"] = &PresortWrapper;
Functions["Descending"] = &PresortWrapper;
Functions["IsKeySwitch"] = &IsKeySwitchWrapper;
@@ -12953,56 +12960,56 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["DependsOn"] = &DependsOnWrapper;
Functions["Seq"] = &SeqWrapper;
Functions["Parameter"] = &ParameterWrapper;
- Functions["WeakField"] = &WeakFieldWrapper;
- Functions["TryWeakMemberFromDict"] = &TryWeakMemberFromDictWrapper;
+ ExtFunctions["WeakField"] = &WeakFieldWrapper;
+ ExtFunctions["TryWeakMemberFromDict"] = &TryWeakMemberFromDictWrapper;
Functions["ByteString"] = &ByteStringWrapper;
Functions["Utf8String"] = &Utf8StringWrapper;
Functions["FromYsonSimpleType"] = &FromYsonSimpleType;
Functions["Mux"] = &MuxWrapper;
Functions["Demux"] = &DemuxWrapper;
- Functions["TimezoneId"] = &TimezoneIdWrapper;
- Functions["TimezoneName"] = &TimezoneNameWrapper;
- Functions["AddTimezone"] = &AddTimezoneWrapper;
+ ExtFunctions["TimezoneId"] = &TimezoneIdWrapper;
+ ExtFunctions["TimezoneName"] = &TimezoneNameWrapper;
+ ExtFunctions["AddTimezone"] = &AddTimezoneWrapper;
Functions["RemoveTimezone"] = &RemoveTimezoneWrapper;
Functions["TypeHandle"] = &TypeHandleWrapper;
Functions["SerializeTypeHandle"] = &SerializeTypeHandleWrapper;
Functions["ParseTypeHandle"] = &ParseTypeHandleWrapper;
Functions["TypeKind"] = &TypeKindWrapper;
Functions["DataTypeComponents"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Data>;
- Functions["DataTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Data>;
- Functions["OptionalTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Optional>;
- Functions["ListTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::List>;
- Functions["StreamTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Stream>;
+ ExtFunctions["DataTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Data>;
+ ExtFunctions["OptionalTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Optional>;
+ ExtFunctions["ListTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::List>;
+ ExtFunctions["StreamTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Stream>;
Functions["TupleTypeComponents"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Tuple>;
- Functions["TupleTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Tuple>;
+ ExtFunctions["TupleTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Tuple>;
Functions["StructTypeComponents"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Struct>;
- Functions["StructTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Struct>;
+ ExtFunctions["StructTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Struct>;
Functions["DictTypeComponents"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Dict>;
- Functions["DictTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Dict>;
+ ExtFunctions["DictTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Dict>;
Functions["ResourceTypeTag"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Resource>;
- Functions["ResourceTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Resource>;
+ ExtFunctions["ResourceTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Resource>;
Functions["TaggedTypeComponents"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Tagged>;
- Functions["TaggedTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Tagged>;
- Functions["VariantTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Variant>;
- Functions["VoidTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Void>;
- Functions["NullTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Null>;
- Functions["EmptyListTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::EmptyList>;
- Functions["EmptyDictTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::EmptyDict>;
- Functions["CallableTypeComponents"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Callable>;
- Functions["CallableArgument"] = &CallableArgumentWrapper;
- Functions["CallableTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Callable>;
- Functions["PgTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Pg>;
+ ExtFunctions["TaggedTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Tagged>;
+ ExtFunctions["VariantTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Variant>;
+ ExtFunctions["VoidTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Void>;
+ ExtFunctions["NullTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Null>;
+ ExtFunctions["EmptyListTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::EmptyList>;
+ ExtFunctions["EmptyDictTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::EmptyDict>;
+ ExtFunctions["CallableTypeComponents"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Callable>;
+ ExtFunctions["CallableArgument"] = &CallableArgumentWrapper;
+ ExtFunctions["CallableTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Callable>;
+ ExtFunctions["PgTypeHandle"] = &MakeTypeHandleWrapper<ETypeAnnotationKind::Pg>;
Functions["PgTypeName"] = &SplitTypeHandleWrapper<ETypeAnnotationKind::Pg>;
Functions["LambdaArgumentsCount"] = LambdaArgumentsCountWrapper;
Functions["LambdaOptionalArgumentsCount"] = LambdaOptionalArgumentsCountWrapper;
Functions["FormatCode"] = &FormatCodeWrapper;
Functions["FormatCodeWithPositions"] = &FormatCodeWrapper;
Functions["SerializeCode"] = &FormatCodeWrapper;
- Functions["WorldCode"] = &MakeCodeWrapper<TExprNode::World>;
- Functions["AtomCode"] = &MakeCodeWrapper<TExprNode::Atom>;
- Functions["ListCode"] = &MakeCodeWrapper<TExprNode::List>;
- Functions["FuncCode"] = &MakeCodeWrapper<TExprNode::Callable>;
- Functions["LambdaCode"] = &MakeCodeWrapper<TExprNode::Lambda>;
+ ExtFunctions["WorldCode"] = &MakeCodeWrapper<TExprNode::World>;
+ ExtFunctions["AtomCode"] = &MakeCodeWrapper<TExprNode::Atom>;
+ ExtFunctions["ListCode"] = &MakeCodeWrapper<TExprNode::List>;
+ ExtFunctions["FuncCode"] = &MakeCodeWrapper<TExprNode::Callable>;
+ ExtFunctions["LambdaCode"] = &MakeCodeWrapper<TExprNode::Lambda>;
Functions["ReprCode"] = &ReprCodeWrapper;
Functions["EvaluateAtom"] = &RestartEvaluationWrapper;
Functions["EvaluateExpr"] = &RestartEvaluationWrapper;
@@ -13066,7 +13073,7 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["ExpandMap"] = &ExpandMapWrapper;
Functions["WideMap"] = &WideMapWrapper;
- Functions["WideFilter"] = &WideFilterWrapper;
+ ExtFunctions["WideFilter"] = &WideFilterWrapper;
Functions["WideTakeWhile"] = &WideWhileWrapper;
Functions["WideSkipWhile"] = &WideWhileWrapper;
Functions["WideTakeWhileInclusive"] = &WideWhileWrapper;
@@ -13084,11 +13091,11 @@ template <NKikimr::NUdf::EDataSlot DataSlot>
Functions["WideFromBlocks"] = &WideFromBlocksWrapper;
Functions["ListFromBlocks"] = &ListFromBlocksWrapper;
- Functions["WideSkipBlocks"] = &WideSkipTakeBlocksWrapper;
- Functions["WideTakeBlocks"] = &WideSkipTakeBlocksWrapper;
+ ExtFunctions["WideSkipBlocks"] = &WideSkipTakeBlocksWrapper;
+ ExtFunctions["WideTakeBlocks"] = &WideSkipTakeBlocksWrapper;
Functions["BlockCompress"] = &BlockCompressWrapper;
- Functions["WideTopBlocks"] = &WideTopBlocksWrapper;
- Functions["WideTopSortBlocks"] = &WideTopBlocksWrapper;
+ ExtFunctions["WideTopBlocks"] = &WideTopBlocksWrapper;
+ ExtFunctions["WideTopSortBlocks"] = &WideTopBlocksWrapper;
Functions["WideSortBlocks"] = &WideSortBlocksWrapper;
Functions["BlockExtend"] = &BlockExtendWrapper;
Functions["BlockOrderedExtend"] = &BlockExtendWrapper;
diff --git a/yql/essentials/core/type_ann/type_ann_list.cpp b/yql/essentials/core/type_ann/type_ann_list.cpp
index 508dad05067..a215fdef950 100644
--- a/yql/essentials/core/type_ann/type_ann_list.cpp
+++ b/yql/essentials/core/type_ann/type_ann_list.cpp
@@ -693,7 +693,7 @@ namespace {
}
} // namespace
- IGraphTransformer::TStatus FilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus FilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureMinMaxArgsCount(*input, 2U, 3U, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -710,7 +710,7 @@ namespace {
if (input->ChildrenSize() > 2U) {
const auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
+ const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
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()));
@@ -1963,7 +1963,7 @@ namespace {
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) {
+ IGraphTransformer::TStatus PrependWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1978,7 +1978,7 @@ namespace {
}
auto expectedType = input->Tail().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- auto convertStatus = TryConvertTo(input->HeadRef(), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->HeadRef(), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
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;
@@ -1990,7 +1990,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus AppendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus AppendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2005,7 +2005,7 @@ namespace {
}
auto expectedType = input->Head().GetTypeAnn()->Cast<TListExprType>()->GetItemType();
- auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Tail().Pos()), "Mismatch type of item being appended and list"));
return IGraphTransformer::TStatus::Error;
@@ -2255,7 +2255,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ListFromRangeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ListFromRangeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureMinMaxArgsCount(*input, 2U, 3U, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -2367,7 +2367,9 @@ namespace {
if (!commonType)
return IGraphTransformer::TStatus::Error;
- if (const auto status = TryConvertTo(input->ChildRef(0U), *commonType, ctx.Expr).Combine(TryConvertTo(input->ChildRef(1U), *commonType, ctx.Expr)); status != IGraphTransformer::TStatus::Ok)
+ if (const auto status = TryConvertTo(input->ChildRef(0U), *commonType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError)
+ .Combine(TryConvertTo(input->ChildRef(1U), *commonType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError));
+ status != IGraphTransformer::TStatus::Ok)
return status;
if (stepIsOpt && ETypeAnnotationKind::Optional != commonType->GetKind()) {
@@ -2489,7 +2491,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus ReplicateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ReplicateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -2500,7 +2502,7 @@ namespace {
}
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, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -3038,7 +3040,7 @@ namespace {
}
template<bool IsStrict>
- IGraphTransformer::TStatus ListExtendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus ListExtendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!input->ChildrenSize()) {
output = ctx.Expr.NewCallable(input->Pos(), "EmptyList", {});
return IGraphTransformer::TStatus::Repeat;
@@ -3070,7 +3072,7 @@ namespace {
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 (const auto status = ConvertChildrenToType(input, commonType, ctx.Expr, ctx.Types.UseTypeDiffForConvertToError); status != IGraphTransformer::TStatus::Ok)
return status;
} else
return IGraphTransformer::TStatus::Error;
@@ -3079,8 +3081,8 @@ namespace {
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, TExtContext& ctx);
+ template IGraphTransformer::TStatus ListExtendWrapper<false>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
IGraphTransformer::TStatus ListUnionAllWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
return ListAutomapArgs(input, output, ctx, "UnionAll");
@@ -3239,7 +3241,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus TopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 4, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3255,7 +3257,7 @@ namespace {
}
const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
- const auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
+ const auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -3270,7 +3272,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus KeepTopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus KeepTopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureArgsCount(*input, 5, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3285,7 +3287,8 @@ namespace {
}
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) {
+ if (const auto convertStatus = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
+ convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Head().Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
}
@@ -3776,7 +3779,8 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus TakeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus TakeWrapperImpl(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx,
+ bool useTypeDiffForConvertToError) {
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -3791,7 +3795,7 @@ namespace {
}
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, {}, useTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -3805,6 +3809,14 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
+ IGraphTransformer::TStatus TakeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ return TakeWrapperImpl(input, output, ctx, false);
+ }
+
+ IGraphTransformer::TStatus TakeWrapperEx(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
+ return TakeWrapperImpl(input, output, ctx, ctx.Types.UseTypeDiffForConvertToError);
+ }
+
IGraphTransformer::TStatus FoldWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
if (!EnsureArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -4298,7 +4310,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus EnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus EnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4318,7 +4330,7 @@ namespace {
const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint64);
if (input->ChildrenSize() > 1) {
- auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(1)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -4330,7 +4342,7 @@ namespace {
}
if (input->ChildrenSize() > 2) {
- auto convertStatus = TryConvertTo(input->ChildRef(2), *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(input->ChildRef(2), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(input->Child(2)->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
@@ -6559,7 +6571,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus WinLeadLagWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus WinLeadLagWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureMinArgsCount(*input, 2, ctx.Expr) || !EnsureMaxArgsCount(*input, 3, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -6586,7 +6598,7 @@ namespace {
auto status = ConvertToLambda(lambdaValue, ctx.Expr, 1);
if (argCount > 2) {
- status = status.Combine(TryConvertTo(input->ChildRef(2), *winOffsetType, ctx.Expr));
+ status = status.Combine(TryConvertTo(input->ChildRef(2), *winOffsetType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError));
}
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
@@ -6652,7 +6664,7 @@ namespace {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus WinNTileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus WinNTileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -6663,7 +6675,7 @@ namespace {
}
auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Int64);
- auto status = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr);
+ auto status = TryConvertTo(input->ChildRef(1), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
diff --git a/yql/essentials/core/type_ann/type_ann_list.h b/yql/essentials/core/type_ann/type_ann_list.h
index abcc3b5ae1b..3e0daa98c90 100644
--- a/yql/essentials/core/type_ann/type_ann_list.h
+++ b/yql/essentials/core/type_ann/type_ann_list.h
@@ -12,7 +12,7 @@ namespace NTypeAnnImpl {
TExprNode::TPtr ExpandToWindowTraits(const TExprNode& input, TExprContext& ctx);
bool ValidateAggManyStreams(const TExprNode& value, ui32 aggCount, TExprContext& ctx);
- IGraphTransformer::TStatus FilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus FilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& 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);
@@ -47,8 +47,8 @@ namespace NTypeAnnImpl {
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 PrependWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
+ IGraphTransformer::TStatus AppendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& 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);
@@ -57,8 +57,8 @@ namespace NTypeAnnImpl {
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 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 ListFromRangeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
+ IGraphTransformer::TStatus ReplicateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& 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);
@@ -66,14 +66,14 @@ namespace NTypeAnnImpl {
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>
- IGraphTransformer::TStatus ListExtendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus ListExtendWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& 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 PruneKeysWrapper(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 TopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
+ IGraphTransformer::TStatus KeepTopWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& 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);
@@ -81,6 +81,7 @@ namespace NTypeAnnImpl {
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 TakeWrapperEx(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& 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);
@@ -91,7 +92,7 @@ namespace NTypeAnnImpl {
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 EnumerateWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& 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);
@@ -117,11 +118,11 @@ namespace NTypeAnnImpl {
IGraphTransformer::TStatus ToWindowTraitsWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus CalcOverWindowWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus CalcOverWindowGroupWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus WinLeadLagWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus WinLeadLagWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
IGraphTransformer::TStatus WinRowNumberWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus WinCumeDistWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus WinRankWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus WinNTileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus WinNTileWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
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);
diff --git a/yql/essentials/core/type_ann/type_ann_pg.cpp b/yql/essentials/core/type_ann/type_ann_pg.cpp
index 61e84e700b9..2b5f7625ca1 100644
--- a/yql/essentials/core/type_ann/type_ann_pg.cpp
+++ b/yql/essentials/core/type_ann/type_ann_pg.cpp
@@ -5187,7 +5187,7 @@ IGraphTransformer::TStatus PgSelectWrapper(const TExprNode::TPtr& input, TExprNo
} else {
const TTypeAnnotationNode* expectedType = ctx.Expr.MakeType<TOptionalExprType>(
ctx.Expr.MakeType<TDataExprType>(EDataSlot::Int64));
- auto convertStatus = TryConvertTo(data, *expectedType, ctx.Expr);
+ auto convertStatus = TryConvertTo(data, *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (convertStatus.Level == IGraphTransformer::TStatus::Error) {
ctx.Expr.AddError(TIssue(ctx.Expr.GetPosition(data->Pos()), "Mismatch argument types"));
return IGraphTransformer::TStatus::Error;
diff --git a/yql/essentials/core/type_ann/type_ann_types.cpp b/yql/essentials/core/type_ann/type_ann_types.cpp
index aa9e2616bf5..30f93bc3d31 100644
--- a/yql/essentials/core/type_ann/type_ann_types.cpp
+++ b/yql/essentials/core/type_ann/type_ann_types.cpp
@@ -1270,7 +1270,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Data>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Data>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1290,7 +1290,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Optional>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Optional>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1305,7 +1305,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::List>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::List>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1320,7 +1320,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Stream>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Stream>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1350,7 +1350,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Tuple>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Tuple>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1358,7 +1358,7 @@ namespace NTypeAnnImpl {
auto resType = MakeTypeHandleResourceType(ctx.Expr);
auto listType = ctx.Expr.MakeType<TListExprType>(resType);
- auto status = TryConvertTo(input->ChildRef(0), *listType, ctx.Expr);
+ auto status = TryConvertTo(input->ChildRef(0), *listType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -1383,7 +1383,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Struct>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Struct>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1391,7 +1391,7 @@ namespace NTypeAnnImpl {
auto itemType = MakeItemDescriptorType(ctx.Expr);
auto listType = ctx.Expr.MakeType<TListExprType>(itemType);
- auto status = TryConvertTo(input->ChildRef(0), *listType, ctx.Expr);
+ auto status = TryConvertTo(input->ChildRef(0), *listType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -1416,7 +1416,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Dict>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Dict>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1450,7 +1450,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Resource>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Resource>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1480,7 +1480,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Tagged>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Tagged>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1499,7 +1499,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Variant>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Variant>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1514,7 +1514,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Void>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Void>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1525,7 +1525,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Null>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Null>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1536,7 +1536,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::EmptyList>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::EmptyList>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1547,7 +1547,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::EmptyDict>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::EmptyDict>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1558,7 +1558,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Pg>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Pg>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1587,7 +1587,7 @@ namespace NTypeAnnImpl {
return IGraphTransformer::TStatus::Ok;
}
- IGraphTransformer::TStatus CallableArgumentWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus CallableArgumentWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
@@ -1602,7 +1602,7 @@ namespace NTypeAnnImpl {
if (input->ChildrenSize() > 1) {
auto optStrType = ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::String));
- auto status = TryConvertTo(input->ChildRef(1), *optStrType, ctx.Expr);
+ auto status = TryConvertTo(input->ChildRef(1), *optStrType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status == IGraphTransformer::TStatus::Error) {
return status;
}
@@ -1610,7 +1610,7 @@ namespace NTypeAnnImpl {
if (input->ChildrenSize() > 2) {
auto optListStrType = ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TListExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::String)));
- auto status = TryConvertTo(input->ChildRef(2), *optListStrType, ctx.Expr);
+ auto status = TryConvertTo(input->ChildRef(2), *optListStrType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status == IGraphTransformer::TStatus::Error) {
return status;
}
@@ -1666,7 +1666,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Callable>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeTypeHandleWrapper<ETypeAnnotationKind::Callable>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureMinArgsCount(*input, 2, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1681,14 +1681,14 @@ namespace NTypeAnnImpl {
}
auto listType = ctx.Expr.MakeType<TListExprType>(MakeArgumentDescriptorType(ctx.Expr));
- auto status = TryConvertTo(input->ChildRef(1), *listType, ctx.Expr);
+ auto status = TryConvertTo(input->ChildRef(1), *listType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status != IGraphTransformer::TStatus::Ok) {
return status;
}
if (input->ChildrenSize() > 2) {
auto optUi32Type = ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32));
- status = TryConvertTo(input->ChildRef(2), *optUi32Type, ctx.Expr);
+ status = TryConvertTo(input->ChildRef(2), *optUi32Type, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -1696,7 +1696,7 @@ namespace NTypeAnnImpl {
if (input->ChildrenSize() > 3) {
auto optStrType = ctx.Expr.MakeType<TOptionalExprType>(ctx.Expr.MakeType<TDataExprType>(EDataSlot::String));
- status = TryConvertTo(input->ChildRef(3), *optStrType, ctx.Expr);
+ status = TryConvertTo(input->ChildRef(3), *optStrType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -1756,7 +1756,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeCodeWrapper<TExprNode::World>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeCodeWrapper<TExprNode::World>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 0, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1767,14 +1767,14 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeCodeWrapper<TExprNode::Atom>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeCodeWrapper<TExprNode::Atom>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::String);
- auto status = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr);
+ auto status = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -1784,7 +1784,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeCodeWrapper<TExprNode::List>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeCodeWrapper<TExprNode::List>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
IGraphTransformer::TStatus status = IGraphTransformer::TStatus::Ok;
for (ui32 i = 0; i < input->ChildrenSize(); ++i) {
@@ -1801,14 +1801,14 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeCodeWrapper<TExprNode::Callable>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeCodeWrapper<TExprNode::Callable>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
}
auto expectedType = ctx.Expr.MakeType<TDataExprType>(EDataSlot::String);
- auto status = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr);
+ auto status = TryConvertTo(input->ChildRef(0), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status != IGraphTransformer::TStatus::Ok) {
return status;
}
@@ -1827,7 +1827,7 @@ namespace NTypeAnnImpl {
}
template <>
- IGraphTransformer::TStatus MakeCodeWrapper<TExprNode::Lambda>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx) {
+ IGraphTransformer::TStatus MakeCodeWrapper<TExprNode::Lambda>(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx) {
Y_UNUSED(output);
if (!EnsureMinArgsCount(*input, 1, ctx.Expr)) {
return IGraphTransformer::TStatus::Error;
@@ -1844,7 +1844,7 @@ namespace NTypeAnnImpl {
}
} else {
auto ui32Type = ctx.Expr.MakeType<TDataExprType>(EDataSlot::Uint32);
- auto status = TryConvertTo(input->ChildRef(0), *ui32Type, ctx.Expr);
+ auto status = TryConvertTo(input->ChildRef(0), *ui32Type, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
if (status.Level != IGraphTransformer::TStatus::Ok) {
return status;
}
diff --git a/yql/essentials/core/type_ann/type_ann_types.h b/yql/essentials/core/type_ann/type_ann_types.h
index ed47a249790..1223b0877e7 100644
--- a/yql/essentials/core/type_ann/type_ann_types.h
+++ b/yql/essentials/core/type_ann/type_ann_types.h
@@ -40,13 +40,13 @@ namespace NTypeAnnImpl {
IGraphTransformer::TStatus SerializeTypeHandleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ParseTypeHandleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus TypeKindWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
- IGraphTransformer::TStatus CallableArgumentWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus CallableArgumentWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
template <ETypeAnnotationKind>
IGraphTransformer::TStatus SplitTypeHandleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
template <ETypeAnnotationKind>
- IGraphTransformer::TStatus MakeTypeHandleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus MakeTypeHandleWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
IGraphTransformer::TStatus FormatCodeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
IGraphTransformer::TStatus ReprCodeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
@@ -54,6 +54,6 @@ namespace NTypeAnnImpl {
IGraphTransformer::TStatus EvaluateExprIfPureWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
template <TExprNode::EType>
- IGraphTransformer::TStatus MakeCodeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TContext& ctx);
+ IGraphTransformer::TStatus MakeCodeWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& ctx);
} // namespace NTypeAnnImpl
} // namespace NYql
diff --git a/yql/essentials/core/type_ann/type_ann_wide.cpp b/yql/essentials/core/type_ann/type_ann_wide.cpp
index 85cc9fba309..4905e85aeef 100644
--- a/yql/essentials/core/type_ann/type_ann_wide.cpp
+++ b/yql/essentials/core/type_ann/type_ann_wide.cpp
@@ -143,14 +143,14 @@ IGraphTransformer::TStatus WideChain1MapWrapper(const TExprNode::TPtr& input, TE
return IGraphTransformer::TStatus::Ok;
}
-IGraphTransformer::TStatus WideFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TContext& ctx) {
+IGraphTransformer::TStatus WideFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr&, TExtContext& 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);
+ const auto convertStatus = TryConvertTo(input->TailRef(), *expectedType, ctx.Expr, {}, ctx.Types.UseTypeDiffForConvertToError);
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()));
diff --git a/yql/essentials/core/type_ann/type_ann_wide.h b/yql/essentials/core/type_ann/type_ann_wide.h
index e5ddb9ff4a4..7b8054b1ffa 100644
--- a/yql/essentials/core/type_ann/type_ann_wide.h
+++ b/yql/essentials/core/type_ann/type_ann_wide.h
@@ -11,7 +11,7 @@ namespace NTypeAnnImpl {
bool ValidateWideTopKeys(TExprNode& keys, const TTypeAnnotationNode::TListType& types, TExprContext& 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 WideFilterWrapper(const TExprNode::TPtr& input, TExprNode::TPtr& output, TExtContext& 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);
diff --git a/yql/essentials/core/yql_expr_type_annotation.cpp b/yql/essentials/core/yql_expr_type_annotation.cpp
index 16e29a60c8e..b3a905d72aa 100644
--- a/yql/essentials/core/yql_expr_type_annotation.cpp
+++ b/yql/essentials/core/yql_expr_type_annotation.cpp
@@ -4246,7 +4246,7 @@ const TTypeAnnotationNode* MakeSequenceType(ETypeAnnotationKind sequenceKind, co
}
IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& expectedType,
- TExprContext& ctx, TConvertFlags flags) {
+ TExprContext& ctx, TConvertFlags flags, bool useTypeDiff) {
if (HasError(node->GetTypeAnn(), ctx)) {
return IGraphTransformer::TStatus::Error;
}
@@ -4270,18 +4270,23 @@ IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnota
return IGraphTransformer::TStatus::Error;
}
- return TryConvertTo(node, *node->GetTypeAnn(), expectedType, ctx, flags);
+ return TryConvertTo(node, *node->GetTypeAnn(), expectedType, ctx, flags, useTypeDiff);
}
IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
- const TTypeAnnotationNode& expectedType, TExprContext& ctx, TConvertFlags flags) {
+ const TTypeAnnotationNode& expectedType, TExprContext& ctx, TConvertFlags flags, bool useTypeDiff) {
if (HasError(node->GetTypeAnn(), ctx)) {
return IGraphTransformer::TStatus::Error;
}
TIssueScopeGuard guard(ctx.IssueManager, [&] {
- return MakeIntrusive<TIssue>(ctx.GetPosition(node->Pos()),
- TStringBuilder() << "Failed to convert type: " << sourceType << " to " << expectedType);
+ if (useTypeDiff) {
+ return MakeIntrusive<TIssue>(ctx.GetPosition(node->Pos()),
+ TStringBuilder() << "Failed to convert, type diff: " << GetTypeDiff(sourceType, expectedType));
+ } else {
+ return MakeIntrusive<TIssue>(ctx.GetPosition(node->Pos()),
+ TStringBuilder() << "Failed to convert type: " << sourceType << " to " << expectedType);
+ }
});
auto status = TryConvertToImpl(ctx, node, sourceType, expectedType, flags, /* raiseIssues */ true);
if (status.Level == IGraphTransformer::TStatus::Error) {
@@ -5008,7 +5013,7 @@ IGraphTransformer::TStatus SilentInferCommonType(TExprNode::TPtr& node1, const T
return IGraphTransformer::TStatus::Error;
}
-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 useTypeDiff) {
if (!input->ChildrenSize()) {
return IGraphTransformer::TStatus::Ok;
}
@@ -5020,7 +5025,7 @@ IGraphTransformer::TStatus ConvertChildrenToType(const TExprNode::TPtr& input, c
return IGraphTransformer::TStatus::Error;
}
- status = status.Combine(TryConvertTo(input->ChildRef(i), *targetType, ctx));
+ status = status.Combine(TryConvertTo(input->ChildRef(i), *targetType, ctx, {}, useTypeDiff));
if (status == IGraphTransformer::TStatus::Error)
break;
}
diff --git a/yql/essentials/core/yql_expr_type_annotation.h b/yql/essentials/core/yql_expr_type_annotation.h
index 9bad092f76c..456d57a7b8e 100644
--- a/yql/essentials/core/yql_expr_type_annotation.h
+++ b/yql/essentials/core/yql_expr_type_annotation.h
@@ -244,9 +244,9 @@ using TConvertFlags = TEnumBitSet<EFlags, DisableTruncation, Last>;
using NConvertFlags::TConvertFlags;
IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
- const TTypeAnnotationNode& expectedType, TExprContext& ctx, TConvertFlags flags = {});
+ const TTypeAnnotationNode& expectedType, TExprContext& ctx, TConvertFlags flags = {}, bool useTypeDiff = false);
IGraphTransformer::TStatus TryConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& expectedType,
- TExprContext& ctx, TConvertFlags flags = {});
+ TExprContext& ctx, TConvertFlags flags = {}, bool useTypeDiff = false);
IGraphTransformer::TStatus TrySilentConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& expectedType, TExprContext& ctx,
TConvertFlags flags = {});
IGraphTransformer::TStatus TrySilentConvertTo(TExprNode::TPtr& node, const TTypeAnnotationNode& sourceType,
@@ -257,7 +257,8 @@ 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 useTypeDiff = false);
bool IsSqlInCollectionItemsNullable(const NNodes::TCoSqlIn& node);
diff --git a/yql/essentials/core/yql_type_annotation.h b/yql/essentials/core/yql_type_annotation.h
index 07908f3bcb5..64ad1207cad 100644
--- a/yql/essentials/core/yql_type_annotation.h
+++ b/yql/essentials/core/yql_type_annotation.h
@@ -387,6 +387,7 @@ struct TTypeAnnotationContext: public TThrRefBase {
TSimpleSharedPtr<NDq::TOrderingsStateMachine> OrderingsFSM;
TLangVersion LangVer = MinLangVersion;
EBackportCompatibleFeaturesMode BackportMode = EBackportCompatibleFeaturesMode::None;
+ bool UseTypeDiffForConvertToError = false;
THashMap<TString, TIntrusivePtr<TOptimizerStatistics::TColumnStatMap>> ColumnStatisticsByTableName;
THashMap<ui64, std::shared_ptr<TOptimizerStatistics>> StatisticsMap;
TIntrusivePtr<ITimeProvider> TimeProvider;
diff --git a/yql/essentials/docs/en/udf/list/string.md b/yql/essentials/docs/en/udf/list/string.md
index 6b8e000c765..3d77857b2e0 100644
--- a/yql/essentials/docs/en/udf/list/string.md
+++ b/yql/essentials/docs/en/udf/list/string.md
@@ -42,7 +42,7 @@ Functions for ASCII strings:
* `String::ReverseFind(String{Flags:AutoMap}, String, [Uint64?]) -> Int64`: Returns the last position found or -1. The optional argument is the offset from the beginning of the string.
-* `String::AsciiStartsWithIgnoreCase(String?, String) -> Bool` Added in the version [2025.02](../../changelog/2025.02.md#string-module)
+* `String::AsciiStartsWithIgnoreCase(String?, String) -> Bool`
* `String::HasPrefix(String?, String) -> Bool`
@@ -52,7 +52,7 @@ Functions for ASCII strings:
* `String::StartsWithIgnoreCase(String?, String) -> Bool` Removed in the version [2025.02](../../changelog/2025.02.md#string-module)
-* `String::AsciiEndsWithIgnoreCase(String?, String) -> Bool` Added in the version [2025.02](../../changelog/2025.02.md#string-module)
+* `String::AsciiEndsWithIgnoreCase(String?, String) -> Bool`
* `String::HasSuffix(String?, String) -> Bool`
diff --git a/yql/essentials/docs/ru/udf/list/string.md b/yql/essentials/docs/ru/udf/list/string.md
index c2bf6ec544c..baaf7ef84f1 100644
--- a/yql/essentials/docs/ru/udf/list/string.md
+++ b/yql/essentials/docs/ru/udf/list/string.md
@@ -62,8 +62,8 @@ SELECT String::Strip("YQL "); -- "YQL"
Устаревшие функции, к использованию не рекомендуются.
-* `String::AsciiStartsWithIgnoreCase(string:String?, prefix:String) -> Bool` - добавлена в версии [2025.02](../../changelog/2025.02.md#string-module)
-* `String::AsciiEndsWithIgnoreCase(string:String?, suffix:String) -> Bool` - добавлена в версии [2025.02](../../changelog/2025.02.md#string-module)
+* `String::AsciiStartsWithIgnoreCase(string:String?, prefix:String) -> Bool`
+* `String::AsciiEndsWithIgnoreCase(string:String?, suffix:String) -> Bool`
* `String::HasPrefixIgnoreCase(string:String?, prefix:String) -> Bool` - удалена в версии [2025.02](../../changelog/2025.02.md#string-module)
* `String::StartsWithIgnoreCase(string:String?, prefix:String) -> Bool` - удалена в версии [2025.02](../../changelog/2025.02.md#string-module)
* `String::HasSuffixIgnoreCase(string:String?, suffix:String) -> Bool` - удалена в версии [2025.02](../../changelog/2025.02.md#string-module)
diff --git a/yql/essentials/minikql/comp_nodes/mkql_block_coalesce.cpp b/yql/essentials/minikql/comp_nodes/mkql_block_coalesce.cpp
index 3d7384147f8..6185b7688b1 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_block_coalesce.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_block_coalesce.cpp
@@ -6,6 +6,7 @@
#include <yql/essentials/minikql/computation/mkql_computation_node_holders.h>
#include <yql/essentials/minikql/mkql_node_builder.h>
#include <yql/essentials/minikql/mkql_node_cast.h>
+#include <yql/essentials/minikql/mkql_type_helper.h>
#include <yql/essentials/public/udf/arrow/block_builder.h>
#include <yql/essentials/public/udf/arrow/block_reader.h>
#include <yql/essentials/public/udf/arrow/util.h>
@@ -118,18 +119,37 @@ bool DispatchBlendingCoalesce(const arrow::Datum& left, const arrow::Datum& righ
}
}
+std::shared_ptr<arrow::Scalar> UnwrapScalar(std::shared_ptr<arrow::Scalar> scalar, bool firstScalarIsExternalOptional) {
+ if (firstScalarIsExternalOptional) {
+ return dynamic_cast<arrow::StructScalar&>(*scalar).value.at(0);
+ }
+ return scalar;
+}
+
class TCoalesceBlockExec {
public:
TCoalesceBlockExec(const std::shared_ptr<arrow::DataType>& returnArrowType, TType* firstItemType, TType* secondItemType, bool needUnwrapFirst)
: ReturnArrowType_(returnArrowType)
, FirstItemType_(firstItemType)
, SecondItemType_(secondItemType)
- , NeedUnwrapFirst_(needUnwrapFirst) {
+ , NeedUnwrapFirst_(needUnwrapFirst)
+ , FirstScalarIsExternalOptional_(NeedWrapWithExternalOptional(FirstItemType_))
+ {
}
arrow::Status Exec(arrow::compute::KernelContext* ctx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) const {
const auto& first = batch.values[0];
const auto& second = batch.values[1];
+
+ if (first.is_scalar() && second.is_scalar()) {
+ if (first.scalar()->is_valid) {
+ *res = NeedUnwrapFirst_ ? UnwrapScalar(first.scalar(), FirstScalarIsExternalOptional_) : first.scalar();
+ } else {
+ *res = second.scalar();
+ }
+ return arrow::Status::OK();
+ }
+
MKQL_ENSURE(!first.is_scalar() || !second.is_scalar(), "Expected at least one array");
size_t length = Max(first.length(), second.length());
auto firstReader = NYql::NUdf::MakeBlockReader(TTypeInfoHelper(), FirstItemType_);
@@ -137,7 +157,7 @@ public:
if (first.is_scalar()) {
auto firstValue = firstReader->GetScalarItem(*first.scalar());
if (firstValue) {
- auto builder = NYql::NUdf::MakeArrayBuilder(TTypeInfoHelper(), SecondItemType_, *ctx->memory_pool(), length, nullptr);
+ auto builder = NYql::NUdf::MakeArrayBuilder(TTypeInfoHelper(), SecondItemType_, *ctx->memory_pool(), length, /*pgBuilder=*/nullptr);
builder->Add(NeedUnwrapFirst_ ? firstValue.GetOptionalValue() : firstValue, length);
*res = builder->Build(true);
} else {
@@ -205,6 +225,7 @@ private:
TType* const FirstItemType_;
TType* const SecondItemType_;
const bool NeedUnwrapFirst_;
+ const bool FirstScalarIsExternalOptional_;
};
std::shared_ptr<arrow::compute::ScalarKernel> MakeBlockCoalesceKernel(const TVector<TType*>& argTypes, TType* resultType, bool needUnwrapFirst) {
diff --git a/yql/essentials/minikql/comp_nodes/mkql_block_exists.cpp b/yql/essentials/minikql/comp_nodes/mkql_block_exists.cpp
index 7df219329e1..f49d3f6b56e 100644
--- a/yql/essentials/minikql/comp_nodes/mkql_block_exists.cpp
+++ b/yql/essentials/minikql/comp_nodes/mkql_block_exists.cpp
@@ -12,6 +12,10 @@ class TBlockExistsExec {
public:
arrow::Status Exec(arrow::compute::KernelContext* ctx, const arrow::compute::ExecBatch& batch, arrow::Datum* res) const {
const auto& input = batch.values[0];
+ if (input.is_scalar()) {
+ *res = arrow::Datum(static_cast<ui8>(input.scalar()->is_valid));
+ return arrow::Status::OK();
+ }
MKQL_ENSURE(input.is_array(), "Expected array");
const auto& arr = *input.array();
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_block_coalesce_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_block_coalesce_ut.cpp
index 4f00f15633c..57ad9137cdf 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_block_coalesce_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_block_coalesce_ut.cpp
@@ -1,16 +1,17 @@
+#include <yql/essentials/ast/yql_expr.h>
#include <yql/essentials/minikql/comp_nodes/mkql_block_coalesce.h>
-#include <yql/essentials/core/arrow_kernels/request/request.h>
#include <yql/essentials/minikql/comp_nodes/mkql_block_coalesce_blending_helper.h>
#include <yql/essentials/minikql/comp_nodes/ut/mkql_computation_node_ut.h>
+#include <yql/essentials/minikql/computation/mkql_block_impl.h>
#include <yql/essentials/minikql/computation/mkql_computation_node_holders.h>
#include <yql/essentials/minikql/computation/mkql_block_builder.h>
#include <yql/essentials/ast/yql_expr_builder.h>
#include <yql/essentials/public/udf/arrow/memory_pool.h>
+#include <yql/essentials/minikql/computation/mkql_block_impl.h>
#include <yql/essentials/minikql/mkql_node_cast.h>
#include <yql/essentials/minikql/arrow/arrow_util.h>
-#include <yql/essentials/core/arrow_kernels/request/request.h>
-#include <yql/essentials/core/arrow_kernels/registry/registry.h>
+#include <yql/essentials/minikql/comp_nodes/ut/mkql_block_helper.h>
#include <arrow/compute/exec_internal.h>
@@ -105,6 +106,15 @@ arrow::Datum GenerateArray(TTypeInfoHelper& typeInfoHelper, TType* type, std::ve
return resultArray;
}
+template <typename T, typename U, typename V>
+void TestScalarCoalesceKernel(T left, U right, V expected) {
+ TSetup<false> setup;
+ TestScalarKernel(left, right, expected, setup,
+ [&](TRuntimeNode left, TRuntimeNode right) {
+ return setup.PgmBuilder->BlockCoalesce(left, right);
+ });
+}
+
enum class ERightOperandType {
SCALAR,
ARRAY,
@@ -116,7 +126,20 @@ template <typename T>
using InputOptionalVector =
std::vector<TMaybe<typename NUdf::TDataType<T>::TLayout>>;
-template <typename T, ERightOperandType rightType = ERightOperandType::ARRAY>
+std::unique_ptr<IArrowKernelComputationNode> GetArrowKernel(IComputationGraph* graph) {
+ std::vector<std::unique_ptr<IArrowKernelComputationNode>> allKernels;
+ for (auto node : graph->GetNodes()) {
+ auto kernelNode = node->PrepareArrowKernelComputationNode(graph->GetContext());
+ if (!kernelNode) {
+ continue;
+ }
+ allKernels.push_back(std::move(kernelNode));
+ }
+ UNIT_ASSERT_EQUAL(allKernels.size(), 1u);
+ return std::move(allKernels[0]);
+}
+
+template <typename T, ERightOperandType rightTypeShape = ERightOperandType::ARRAY>
void TestBlockCoalesceForVector(InputOptionalVector<T> left,
InputOptionalVector<T> right,
InputOptionalVector<T> expected,
@@ -125,29 +148,22 @@ void TestBlockCoalesceForVector(InputOptionalVector<T> left,
using TLayout = typename NUdf::TDataType<T>::TLayout;
TSetup<false> setup;
NYql::TExprContext exprCtx;
- auto* type = setup.PgmBuilder->NewDataType(NUdf::TDataType<T>::Id);
- auto* typeNode = exprCtx.template MakeType<NYql::TBlockExprType>(
- exprCtx.template MakeType<NYql::TDataExprType>(NUdf::TDataType<T>::Slot));
-
- auto* optType = setup.PgmBuilder->NewOptionalType(type);
- auto* optTypeNode = exprCtx.template MakeType<NYql::TBlockExprType>(
- exprCtx.template MakeType<NYql::TOptionalExprType>(
- exprCtx.template MakeType<NYql::TDataExprType>(NUdf::TDataType<T>::Slot)));
- if (rightType == ERightOperandType::OPTIONAL_ARRAY || rightType == ERightOperandType::OPTIONAL_SCALAR) {
+ auto* rightType = setup.PgmBuilder->NewDataType(NUdf::TDataType<T>::Id);
+ auto* leftType = setup.PgmBuilder->NewOptionalType(rightType);
+ if (rightTypeShape == ERightOperandType::OPTIONAL_ARRAY || rightTypeShape == ERightOperandType::OPTIONAL_SCALAR) {
// Make both operands optional.
- type = optType;
- typeNode = optTypeNode;
+ rightType = leftType;
}
TTypeInfoHelper typeInfoHelper;
- arrow::Datum leftOperand = GenerateArray(typeInfoHelper, optType, left, leftOffset);
+ arrow::Datum leftOperand = GenerateArray(typeInfoHelper, leftType, left, leftOffset);
arrow::compute::ExecContext execCtx;
arrow::compute::KernelContext ctx(&execCtx);
arrow::Datum rightOperand;
- if constexpr (rightType == ERightOperandType::SCALAR) {
+ if constexpr (rightTypeShape == ERightOperandType::SCALAR) {
rightOperand = MakeScalarDatum<TLayout>(right[0].GetRef());
- } else if constexpr (rightType == ERightOperandType::OPTIONAL_SCALAR) {
+ } else if constexpr (rightTypeShape == ERightOperandType::OPTIONAL_SCALAR) {
if (right[0]) {
rightOperand = MakeScalarDatum<TLayout>(right[0].GetRef());
} else {
@@ -155,25 +171,21 @@ void TestBlockCoalesceForVector(InputOptionalVector<T> left,
rightOperand.scalar()->is_valid = false;
}
} else {
- rightOperand = GenerateArray(typeInfoHelper, type, right, rightOffset);
+ rightOperand = GenerateArray(typeInfoHelper, rightType, right, rightOffset);
}
auto bi = arrow::compute::detail::ExecBatchIterator::Make({leftOperand, rightOperand}, 1000).ValueOrDie();
arrow::compute::ExecBatch batch;
UNIT_ASSERT(bi->Next(&batch));
- std::shared_ptr<arrow::DataType> arrowType;
- UNIT_ASSERT(ConvertArrowType(type, arrowType, [](TType*) {}));
arrow::Datum out;
- auto registry = CreateFunctionRegistry(CreateBuiltinRegistry());
- NYql::TKernelRequestBuilder b(*registry);
-
- b.AddBinaryOp(NYql::TKernelRequestBuilder::EBinaryOp::Coalesce, optTypeNode, typeNode, optTypeNode);
- auto serializedNode = b.Serialize();
- auto nodeFactory = GetBuiltinFactory();
- auto kernel = NYql::LoadKernels(serializedNode, *registry, nodeFactory);
- Y_ENSURE(kernel.size() == 1);
- Y_ENSURE(kernel[0]->exec(&ctx, batch, &out).ok());
-
- arrow::Datum expectedArrowArray = GenerateArray(typeInfoHelper, type, expected, 0);
+ // This graph will never be executed. We need it only to extrace coalesce arrow kernel.
+ auto graph = setup.BuildGraph(
+ setup.PgmBuilder->BlockCoalesce(
+ setup.PgmBuilder->Arg(setup.PgmBuilder->NewBlockType(leftType, TBlockType::EShape::Many)),
+ setup.PgmBuilder->Arg(setup.PgmBuilder->NewBlockType(rightType, TBlockType::EShape::Many))));
+ auto kernel = GetArrowKernel(graph.Get());
+ // kernel is exectly coalesce kernel.
+ Y_ENSURE(kernel->GetArrowKernel().exec(&ctx, batch, &out).ok());
+ arrow::Datum expectedArrowArray = GenerateArray(typeInfoHelper, rightType, expected, 0);
UNIT_ASSERT_EQUAL_C(out, expectedArrowArray, "Expected : " << expectedArrowArray.make_array()->ToString() << "\n but got : " << out.make_array()->ToString());
}
@@ -337,6 +349,23 @@ UNIT_TEST_WITH_INTEGER(KernelRightIsOptionalValidScalar) {
{77, 2, 3, 77, 5, 6, 7, max, 9, 77, 11, 12, 13, 77, 77, 77, min, 77, 19, 20});
}
-} // Y_UNIT_TEST_SUITE(TMiniKQLBlockCoalesceTest)
+Y_UNIT_TEST(OptionalScalar) {
+ TestScalarCoalesceKernel(TMaybe<i32>{16}, 5, 16);
+ TestScalarCoalesceKernel(TMaybe<i32>(), 4, 4);
+ TestScalarCoalesceKernel(TMaybe<i32>(18), TMaybe<i32>(3), TMaybe<i32>(18));
+ TestScalarCoalesceKernel(TMaybe<i32>(), TMaybe<i32>(2), TMaybe<i32>(2));
+}
+Y_UNIT_TEST(ExternalOptionalScalar) {
+ using TDoubleMaybe = TMaybe<TMaybe<i32>>;
+ using TSingleMaybe = TMaybe<i32>;
+
+ TestScalarCoalesceKernel(TDoubleMaybe{TSingleMaybe{25}}, TSingleMaybe{1}, TSingleMaybe{25});
+ TestScalarCoalesceKernel(TDoubleMaybe(TSingleMaybe()), TSingleMaybe(9), TSingleMaybe());
+ TestScalarCoalesceKernel(TDoubleMaybe(), TSingleMaybe(8), TSingleMaybe(8));
+ TestScalarCoalesceKernel(TDoubleMaybe(TSingleMaybe(33)), TDoubleMaybe(TSingleMaybe(7)), TDoubleMaybe(TSingleMaybe(33)));
+ TestScalarCoalesceKernel(TDoubleMaybe(), TDoubleMaybe(TSingleMaybe(6)), TDoubleMaybe(TSingleMaybe(6)));
+}
+
+} // Y_UNIT_TEST_SUITE(TMiniKQLBlockCoalesceTest)
} // namespace NKikimr::NMiniKQL
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_block_exists_ut.cpp b/yql/essentials/minikql/comp_nodes/ut/mkql_block_exists_ut.cpp
index 3b9d41e2b9b..6d0b9915171 100644
--- a/yql/essentials/minikql/comp_nodes/ut/mkql_block_exists_ut.cpp
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_block_exists_ut.cpp
@@ -2,12 +2,22 @@
#include <yql/essentials/minikql/computation/mkql_computation_node_holders.h>
#include <yql/essentials/minikql/computation/mkql_block_builder.h>
+#include <yql/essentials/minikql/comp_nodes/ut/mkql_block_helper.h>
namespace NKikimr {
namespace NMiniKQL {
namespace {
+template <typename T, typename U>
+void TestScalarExistsKernel(T operand, U expected) {
+ TSetup<false> setup;
+ TestScalarKernel(operand, expected, setup,
+ [&](TRuntimeNode node) {
+ return setup.PgmBuilder->BlockExists(node);
+ });
+}
+
void DoBlockExistsOffset(size_t length, size_t offset) {
TSetup<false> setup;
TProgramBuilder& pb = *setup.PgmBuilder;
@@ -109,6 +119,11 @@ Y_UNIT_TEST(ExistsWithOffset) {
}
}
+Y_UNIT_TEST(ScalarExists) {
+ TestScalarExistsKernel(TMaybe<ui32>(), false);
+ TestScalarExistsKernel(TMaybe<ui32>(6), true);
+}
+
} // Y_UNIT_TEST_SUITE
} // namespace NMiniKQL
diff --git a/yql/essentials/minikql/comp_nodes/ut/mkql_block_helper.h b/yql/essentials/minikql/comp_nodes/ut/mkql_block_helper.h
new file mode 100644
index 00000000000..a74aca399ea
--- /dev/null
+++ b/yql/essentials/minikql/comp_nodes/ut/mkql_block_helper.h
@@ -0,0 +1,111 @@
+#include <yql/essentials/ast/yql_expr.h>
+#include <yql/essentials/minikql/comp_nodes/ut/mkql_computation_node_ut.h>
+#include <yql/essentials/minikql/computation/mkql_computation_node_holders.h>
+
+namespace NKikimr::NMiniKQL {
+
+// Template to count TMaybe nesting levels
+template <typename T>
+struct TMaybeTraits {
+ static constexpr ui32 value = 0;
+ using ResultType = T;
+};
+
+template <typename T>
+struct TMaybeTraits<TMaybe<T>> {
+ static constexpr ui32 value = 1 + TMaybeTraits<T>::value;
+ using ResultType = TMaybeTraits<T>::ResultType;
+};
+
+// Template to get the value of the deepest set TMaybe or return 0
+template <typename T>
+TMaybeTraits<T>::ResultType GetInnerValue(const T& value) {
+ if constexpr (TMaybeTraits<T>::value == 0) {
+ // Base case: not a TMaybe type, return the value itself
+ return value;
+ } else {
+ // TMaybe type
+ if (value.Defined()) {
+ return GetInnerValue(value.GetRef());
+ } else {
+ return {}; // Return 0 if not set
+ }
+ }
+}
+
+// Template to get the level of the set TMaybe (returns 0 if not set)
+template <typename T>
+ui32 GetSettedLevel(const T& value) {
+ if constexpr (TMaybeTraits<T>::value == 0) {
+ // Base case: not a TMaybe type, always set at level 0
+ return 0;
+ } else {
+ // TMaybe type
+ if (value.Defined()) {
+ return 1 + GetSettedLevel(value.GetRef());
+ } else {
+ return 0; // Return 0 if not set
+ }
+ }
+}
+
+template<typename T>
+struct TUnpackedMaybe {
+ ui32 SettedLevel;
+ ui32 MaybeLevel;
+ T Value;
+};
+
+template <typename T>
+TRuntimeNode ConvertMaybeToNode(TUnpackedMaybe<T> maybe, TSetup<false>& setup) {
+ auto data = setup.PgmBuilder->NewDataLiteral<T>(maybe.Value);
+
+ for (ui32 i = maybe.SettedLevel; i < maybe.MaybeLevel; i++) {
+ data = setup.PgmBuilder->NewEmptyOptional(setup.PgmBuilder->NewOptionalType(data.GetStaticType()));
+ }
+
+ for (ui32 i = 0; i < maybe.SettedLevel; i++) {
+ data = setup.PgmBuilder->NewOptional(data);
+ }
+
+ data = setup.PgmBuilder->AsScalar(data);
+ return data;
+}
+
+template <typename T, typename U, typename V>
+void TestScalarKernel(T left, U right, V expected, TSetup<false>& setup, std::function<TRuntimeNode(TRuntimeNode, TRuntimeNode)> binaryOp) {
+ NYql::TExprContext exprCtx;
+ TUnpackedMaybe leftUnpacked{.SettedLevel = GetSettedLevel(left), .MaybeLevel = TMaybeTraits<T>::value, .Value = GetInnerValue(left)};
+ TUnpackedMaybe rightUnpacked{.SettedLevel = GetSettedLevel(right), .MaybeLevel = TMaybeTraits<U>::value, .Value = GetInnerValue(right)};
+ TUnpackedMaybe expectedUnpacked{.SettedLevel = GetSettedLevel(expected), .MaybeLevel = TMaybeTraits<V>::value, .Value = GetInnerValue(expected)};
+ auto leftNode = ConvertMaybeToNode(leftUnpacked, setup);
+ auto rightNode = ConvertMaybeToNode(rightUnpacked, setup);
+ auto expectedNode = ConvertMaybeToNode(expectedUnpacked, setup);
+
+ auto resultValue = setup.BuildGraph(binaryOp(leftNode, rightNode))->GetValue();
+ auto expectedValue = setup.BuildGraph(expectedNode)->GetValue();
+
+ auto outDatum = TArrowBlock::From(resultValue).GetDatum();
+ auto expectedDatum = TArrowBlock::From(expectedValue).GetDatum();
+
+ UNIT_ASSERT_EQUAL_C(outDatum, expectedDatum, "Expected : " << outDatum.scalar()->ToString() << "\n but got : " << expectedDatum.scalar()->ToString());
+}
+
+template <typename T, typename V>
+void TestScalarKernel(T left, V expected, TSetup<false>& setup, std::function<TRuntimeNode(TRuntimeNode)> unaryOp) {
+ NYql::TExprContext exprCtx;
+ TUnpackedMaybe unpacked{.SettedLevel = GetSettedLevel(left), .MaybeLevel = TMaybeTraits<T>::value, .Value = GetInnerValue(left)};
+ TUnpackedMaybe expectedUnpacked{.SettedLevel = GetSettedLevel(expected), .MaybeLevel = TMaybeTraits<V>::value, .Value = GetInnerValue(expected)};
+ auto node = ConvertMaybeToNode(unpacked, setup);
+ auto expectedNode = ConvertMaybeToNode(expectedUnpacked, setup);
+
+ auto resultValue = setup.BuildGraph(unaryOp(node))->GetValue();
+ auto expectedValue = setup.BuildGraph(expectedNode)->GetValue();
+
+ auto outDatum = TArrowBlock::From(resultValue).GetDatum();
+ auto expectedDatum = TArrowBlock::From(expectedValue).GetDatum();
+
+ UNIT_ASSERT_EQUAL_C(outDatum, expectedDatum, "Expected : " << outDatum.scalar()->ToString() << "\n but got : " << expectedDatum.scalar()->ToString());
+}
+
+} // namespace NKikimr::NMiniKQL
diff --git a/yql/essentials/minikql/comp_nodes/ut/ya.make.inc b/yql/essentials/minikql/comp_nodes/ut/ya.make.inc
index 4ce865905c9..6f7138c5edc 100644
--- a/yql/essentials/minikql/comp_nodes/ut/ya.make.inc
+++ b/yql/essentials/minikql/comp_nodes/ut/ya.make.inc
@@ -84,8 +84,6 @@ SET(ORIG_SOURCES
)
PEERDIR(
- yql/essentials/core/arrow_kernels/request
- yql/essentials/core/arrow_kernels/registry
yql/essentials/public/udf
yql/essentials/public/udf/arrow
yql/essentials/public/udf/service/exception_policy
diff --git a/yql/essentials/minikql/computation/mkql_block_impl.cpp b/yql/essentials/minikql/computation/mkql_block_impl.cpp
index e960e8562e3..0f16206c112 100644
--- a/yql/essentials/minikql/computation/mkql_block_impl.cpp
+++ b/yql/essentials/minikql/computation/mkql_block_impl.cpp
@@ -7,6 +7,7 @@
#include <yql/essentials/minikql/mkql_node_cast.h>
#include <yql/essentials/minikql/arrow/arrow_util.h>
#include <yql/essentials/minikql/arrow/mkql_bit_utils.h>
+#include <yql/essentials/minikql/mkql_type_helper.h>
#include <yql/essentials/public/udf/arrow/args_dechunker.h>
#include <yql/essentials/parser/pg_wrapper/interface/arrow.h>
@@ -33,6 +34,7 @@ namespace NKikimr::NMiniKQL {
namespace {
+// TODO(YQL): This must be rewrited via traits dispatcher.
template<typename T>
arrow::Datum DoConvertScalar(TType* type, const T& value, arrow::MemoryPool& pool) {
std::shared_ptr<arrow::DataType> arrowType;
@@ -40,15 +42,13 @@ arrow::Datum DoConvertScalar(TType* type, const T& value, arrow::MemoryPool& poo
if (!value) {
return arrow::MakeNullScalar(arrowType);
}
+ auto needWrapWithExternalOptional = NeedWrapWithExternalOptional(type);
- bool isOptional = false;
if (type->IsOptional()) {
type = AS_TYPE(TOptionalType, type)->GetItemType();
- isOptional = true;
}
- if (type->IsOptional() || (isOptional && type->IsPg())) {
- // nested optionals
+ if (needWrapWithExternalOptional) {
std::vector<std::shared_ptr<arrow::Scalar>> arrowValue;
arrowValue.emplace_back(DoConvertScalar(type, value.GetOptionalValue(), pool).scalar());
return arrow::Datum(std::make_shared<arrow::StructScalar>(arrowValue, arrowType));
diff --git a/yql/essentials/minikql/mkql_runtime_version.h b/yql/essentials/minikql/mkql_runtime_version.h
index be71a1646f3..eb64e14b02b 100644
--- a/yql/essentials/minikql/mkql_runtime_version.h
+++ b/yql/essentials/minikql/mkql_runtime_version.h
@@ -24,7 +24,7 @@ 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 62U
+#define MKQL_RUNTIME_VERSION 63U
#endif
// History:
diff --git a/yql/essentials/minikql/mkql_type_builder.cpp b/yql/essentials/minikql/mkql_type_builder.cpp
index f6e529a4a37..cc70d26e5ee 100644
--- a/yql/essentials/minikql/mkql_type_builder.cpp
+++ b/yql/essentials/minikql/mkql_type_builder.cpp
@@ -3,6 +3,7 @@
#include "mkql_node_builder.h"
#include "mkql_alloc.h"
+#include <yql/essentials/minikql/mkql_type_helper.h>
#include <yql/essentials/public/udf/udf_type_ops.h>
#include <yql/essentials/public/udf/arrow/block_item_comparator.h>
#include <yql/essentials/public/udf/arrow/block_item_hasher.h>
@@ -1555,17 +1556,7 @@ bool ConvertArrowTypeImpl(NUdf::EDataSlot slot, std::shared_ptr<arrow::DataType>
}
}
-inline bool IsSingularType(const TType* type) {
- return type->IsNull() ||
- type->IsVoid() ||
- type->IsEmptyDict() ||
- type->IsEmptyList();
-}
-
-inline bool NeedWrapWithExternalOptional(const TType* type) {
- return type->IsPg() || IsSingularType(type);
-}
-
+// TODO(YQL): This must be rewrited via traits dispatcher.
bool ConvertArrowTypeImpl(TType* itemType, std::shared_ptr<arrow::DataType>& type, const TArrowConvertFailedCallback& onFail, bool output) {
bool isOptional;
auto unpacked = UnpackOptional(itemType, isOptional);
@@ -1578,7 +1569,7 @@ bool ConvertArrowTypeImpl(TType* itemType, std::shared_ptr<arrow::DataType>& typ
return false;
}
- if (unpacked->IsOptional() || isOptional && NeedWrapWithExternalOptional(unpacked)) {
+ if (NeedWrapWithExternalOptional(itemType)) {
ui32 nestLevel = 0;
auto currentType = itemType;
auto previousType = itemType;
@@ -1588,7 +1579,7 @@ bool ConvertArrowTypeImpl(TType* itemType, std::shared_ptr<arrow::DataType>& typ
currentType = AS_TYPE(TOptionalType, currentType)->GetItemType();
} while (currentType->IsOptional());
- if (NeedWrapWithExternalOptional(currentType)) {
+ if (NeedWrapWithExternalOptional(previousType)) {
previousType = currentType;
++nestLevel;
}
diff --git a/yql/essentials/minikql/mkql_type_helper.h b/yql/essentials/minikql/mkql_type_helper.h
new file mode 100644
index 00000000000..87832b6e09f
--- /dev/null
+++ b/yql/essentials/minikql/mkql_type_helper.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <yql/essentials/minikql/mkql_node_builder.h>
+
+namespace NKikimr::NMiniKQL {
+
+inline bool IsSingularType(const TType* type) {
+ return type->IsNull() ||
+ type->IsVoid() ||
+ type->IsEmptyDict() ||
+ type->IsEmptyList();
+}
+
+inline bool NeedWrapWithExternalOptional(TType* type) {
+ bool isOptional;
+ auto unpacked = UnpackOptional(type, isOptional);
+ if (!isOptional) {
+ return false;
+ } else if (unpacked->IsOptional()) {
+ return true;
+ } else if (unpacked->IsPg() || IsSingularType(unpacked)) {
+ return true;
+ }
+ return false;
+}
+
+} // namespace NKikimr::NMiniKQL
diff --git a/yql/essentials/providers/common/proto/gateways_config.proto b/yql/essentials/providers/common/proto/gateways_config.proto
index 86fd7f82544..52210fd4d31 100644
--- a/yql/essentials/providers/common/proto/gateways_config.proto
+++ b/yql/essentials/providers/common/proto/gateways_config.proto
@@ -657,7 +657,7 @@ message TMongoDbDataSourceOptions {
// Returns a key-value pair of ObjectID primary key and a JSON serialized document
JSON = 3;
};
-
+
// Ways of dealing with values read in ReadSplit whose types are inconsistent with types that were deduced in DescribeTable
enum EUnexpectedTypeDisplayMode {
UNEXPECTED_UNSPECIFIED = 0;
@@ -671,7 +671,7 @@ message TMongoDbDataSourceOptions {
UNSUPPORTED_OMIT = 1;
UNSUPPORTED_AS_STRING = 2;
};
-
+
optional EReadingMode reading_mode = 1;
optional EUnexpectedTypeDisplayMode unexpected_type_display_mode = 2;
optional EUnsupportedTypeDisplayMode unsupported_type_display_mode = 3;
@@ -851,7 +851,7 @@ message TGenericGatewayConfig {
//
// The list of Connectors.
- //
+ //
// When a request is served, firstly this list is checked.
// If the list has a connector for a request's EGenericDataSourceKind it will
// be applied to that request; otherwise, the "Default Connector" is used.
@@ -869,6 +869,9 @@ message TGenericGatewayConfig {
// [http|https]://host:port/ydbc/cloud-prod/
optional string YdbMvpEndpoint = 7;
+ // Defines timeout for calling the Connector API method `DescribeTable`
+ optional uint64 DescribeTableTimeoutSeconds = 9;
+
repeated TAttr DefaultSettings = 6;
reserved 1, 2;
diff --git a/yql/essentials/public/purecalc/common/type_from_schema.cpp b/yql/essentials/public/purecalc/common/type_from_schema.cpp
index dafb4b29768..d4f12043a13 100644
--- a/yql/essentials/public/purecalc/common/type_from_schema.cpp
+++ b/yql/essentials/public/purecalc/common/type_from_schema.cpp
@@ -21,10 +21,8 @@ namespace {
const auto* expectedItem = expected->GetItems()[*expectedIndex]->GetItemType();
auto arg = ctx.NewArgument(TPositionHandle(), "arg");
- auto fieldConversionStatus = TrySilentConvertTo(arg, *gotItem, *expectedItem, ctx);
+ auto fieldConversionStatus = TryConvertTo(arg, *gotItem, *expectedItem, ctx, {}, true);
if (fieldConversionStatus.Level == IGraphTransformer::TStatus::Error) {
- REPORT("Item " << TString{gotNamedItem->GetName()}.Quote() << " expected to be " <<
- *expectedItem << ", but got " << *gotItem);
status = false;
}
} else {
diff --git a/yql/essentials/public/purecalc/common/worker_factory.cpp b/yql/essentials/public/purecalc/common/worker_factory.cpp
index 9cd1ce129bd..ea1a4ee5187 100644
--- a/yql/essentials/public/purecalc/common/worker_factory.cpp
+++ b/yql/essentials/public/purecalc/common/worker_factory.cpp
@@ -167,6 +167,7 @@ TExprNode::TPtr TWorkerFactory<TBase>::Compile(
IModuleResolver::TPtr moduleResolver = factoryModuleResolver ? factoryModuleResolver->CreateMutableChild() : nullptr;
typeContext = MakeIntrusive<TTypeAnnotationContext>();
typeContext->LangVer = langver;
+ typeContext->UseTypeDiffForConvertToError = true;
typeContext->RandomProvider = CreateDefaultRandomProvider();
typeContext->TimeProvider = DeterministicTimeProviderSeed_ ?
CreateDeterministicTimeProvider(*DeterministicTimeProviderSeed_) :
diff --git a/yql/essentials/public/purecalc/ut/fake_spec.cpp b/yql/essentials/public/purecalc/ut/fake_spec.cpp
index b56f7cfdfd5..8acdbcfb347 100644
--- a/yql/essentials/public/purecalc/ut/fake_spec.cpp
+++ b/yql/essentials/public/purecalc/ut/fake_spec.cpp
@@ -32,5 +32,51 @@ namespace NYql {
spec.Schema = MakeFakeSchema(pg);
return spec;
}
+
+ NYT::TNode CreateTypeNode(const TString& fieldType) {
+ return NYT::TNode::CreateList()
+ .Add("DataType")
+ .Add(fieldType);
+ }
+
+ NYT::TNode CreateOptionalTypeNode(const TString& fieldType) {
+ return NYT::TNode::CreateList()
+ .Add("OptionalType")
+ .Add(CreateTypeNode(fieldType));
+ }
+
+ void AddField(NYT::TNode& node, const TString& fieldName, const TString& fieldType) {
+ node.Add(
+ NYT::TNode::CreateList()
+ .Add(fieldName)
+ .Add(CreateOptionalTypeNode(fieldType))
+ );
+ }
+
+ NYT::TNode MakeFakeStructSchema() {
+ auto structMembers = NYT::TNode::CreateList();
+ AddField(structMembers, "Id", "Uint32");
+ AddField(structMembers, "Name", "Utf8");
+ AddField(structMembers, "Body", "String");
+
+ auto rootMembers = NYT::TNode::CreateList();
+ rootMembers.Add(
+ NYT::TNode::CreateList()
+ .Add("_r")
+ .Add(NYT::TNode::CreateList()
+ .Add("StructType")
+ .Add(std::move(structMembers)))
+ );
+
+ return NYT::TNode::CreateList()
+ .Add("StructType")
+ .Add(std::move(rootMembers));
+ }
+
+ TFakeOutputSpec FakeStructOS() {
+ auto spec = TFakeOutputSpec();
+ spec.Schema = MakeFakeStructSchema();
+ return spec;
+ }
}
}
diff --git a/yql/essentials/public/purecalc/ut/fake_spec.h b/yql/essentials/public/purecalc/ut/fake_spec.h
index 3cb1457f01d..5f2ea310821 100644
--- a/yql/essentials/public/purecalc/ut/fake_spec.h
+++ b/yql/essentials/public/purecalc/ut/fake_spec.h
@@ -50,5 +50,6 @@ namespace NYql {
NYT::TNode MakeFakeSchema(bool pg = false);
TFakeInputSpec FakeIS(ui32 inputsNumber = 1, bool pg = false);
TFakeOutputSpec FakeOS(bool pg = false);
+ TFakeOutputSpec FakeStructOS();
}
}
diff --git a/yql/essentials/public/purecalc/ut/test_sql.cpp b/yql/essentials/public/purecalc/ut/test_sql.cpp
index 2975f784b73..1b6b69279a8 100644
--- a/yql/essentials/public/purecalc/ut/test_sql.cpp
+++ b/yql/essentials/public/purecalc/ut/test_sql.cpp
@@ -33,6 +33,27 @@ Y_UNIT_TEST_SUITE(TestSql) {
UNIT_ASSERT_VALUES_EQUAL(expectedIssues, program->GetIssues().ToString());
}
+ Y_UNIT_TEST(TestStructCastMessage) {
+ auto factory = MakeProgramFactory();
+
+ auto sql = TString(R"(
+ $l = ($x) -> {
+ return <| Id: $x.Name, Name: CAST($x.Name AS String), Body: Just('foo') |>;
+ };
+
+ SELECT $l(TableRow()) AS _r FROM Input
+ )");
+
+ try {
+ factory->MakePullListProgram(FakeIS(), FakeStructOS(), sql, ETranslationMode::SQL);
+ UNIT_ASSERT_C(false, "Unreachable");
+ } catch (const NYql::NPureCalc::TCompileError& error) {
+ auto issue = error.GetIssues();
+ UNIT_ASSERT_C(issue.Contains("Failed to convert 'Id': Int32 to Optional<Uint32>"), issue);
+ UNIT_ASSERT_C(!issue.Contains("Body"), issue);
+ }
+ }
+
Y_UNIT_TEST(TestSqlCompileSingleUnnamedInput) {
auto factory = MakeProgramFactory();
diff --git a/yql/essentials/public/udf/arrow/dispatch_traits.h b/yql/essentials/public/udf/arrow/dispatch_traits.h
index 93d7084296e..f49b2861630 100644
--- a/yql/essentials/public/udf/arrow/dispatch_traits.h
+++ b/yql/essentials/public/udf/arrow/dispatch_traits.h
@@ -86,8 +86,7 @@ std::unique_ptr<typename TTraits::TResult> DispatchByArrowTraits(const ITypeInfo
unpacked = SkipTaggedType(typeInfoHelper, unpacked);
- TOptionalTypeInspector unpackedOpt(typeInfoHelper, unpacked);
- if (unpackedOpt || (typeOpt && NeedWrapWithExternalOptional(typeInfoHelper, unpacked))) {
+ if (NeedWrapWithExternalOptional(typeInfoHelper, type)) {
ui32 nestLevel = 0;
auto currentType = type;
auto previousType = type;
@@ -107,7 +106,7 @@ std::unique_ptr<typename TTraits::TResult> DispatchByArrowTraits(const ITypeInfo
}
}
- if (NeedWrapWithExternalOptional(typeInfoHelper, currentType)) {
+ if (NeedWrapWithExternalOptional(typeInfoHelper, previousType)) {
previousType = currentType;
++nestLevel;
}
diff --git a/yql/essentials/public/udf/arrow/util.h b/yql/essentials/public/udf/arrow/util.h
index a4e430aa4ad..a7d5018b558 100644
--- a/yql/essentials/public/udf/arrow/util.h
+++ b/yql/essentials/public/udf/arrow/util.h
@@ -251,9 +251,18 @@ inline bool IsSingularType(const ITypeInfoHelper& typeInfoHelper, const TType* t
const TType* SkipTaggedType(const ITypeInfoHelper& typeInfoHelper, const TType* type);
inline bool NeedWrapWithExternalOptional(const ITypeInfoHelper& typeInfoHelper, const TType* type) {
- type = SkipTaggedType(typeInfoHelper, type);
-
- return TPgTypeInspector(typeInfoHelper, type) || IsSingularType(typeInfoHelper, type);
+ TOptionalTypeInspector typeOpt(typeInfoHelper, type);
+ if (!typeOpt) {
+ return false;
+ }
+ type = SkipTaggedType(typeInfoHelper, typeOpt.GetItemType());
+ TOptionalTypeInspector typeOptOpt(typeInfoHelper, type);
+ if (typeOptOpt) {
+ return true;
+ } else if (TPgTypeInspector(typeInfoHelper, type) || IsSingularType(typeInfoHelper, type)) {
+ return true;
+ }
+ return false;
}
} // namespace NUdf
diff --git a/yql/essentials/sql/v1/complete/analysis/global/column.cpp b/yql/essentials/sql/v1/complete/analysis/global/column.cpp
new file mode 100644
index 00000000000..7e185697d3f
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/analysis/global/column.cpp
@@ -0,0 +1,116 @@
+#include "column.h"
+
+#include "narrowing_visitor.h"
+
+#include <yql/essentials/sql/v1/complete/syntax/format.h>
+
+namespace NSQLComplete {
+
+ namespace {
+
+ // TODO: Extract it to `identifier.cpp` and reuse it also at `use.cpp`
+ // and replace `GetId` at `parse_tree.cpp`.
+ class TIdentifierVisitor: public SQLv1Antlr4BaseVisitor {
+ public:
+ std::any visitCluster_expr(SQLv1::Cluster_exprContext* ctx) override {
+ if (auto* x = ctx->pure_column_or_named()) {
+ return visit(x);
+ }
+ return {};
+ }
+
+ std::any visitTable_key(SQLv1::Table_keyContext* ctx) override {
+ if (auto* x = ctx->id_table_or_type()) {
+ return visit(x);
+ }
+ return {};
+ }
+
+ std::any visitTerminal(antlr4::tree::TerminalNode* node) override {
+ TString text = GetText(node);
+ switch (node->getSymbol()->getType()) {
+ case SQLv1::TOKEN_ID_QUOTED: {
+ text = Unquoted(std::move(text));
+ } break;
+ }
+ return text;
+ }
+
+ private:
+ TString GetText(antlr4::tree::ParseTree* tree) const {
+ return TString(tree->getText());
+ }
+ };
+
+ TMaybe<TString> GetId(antlr4::ParserRuleContext* ctx) {
+ if (ctx == nullptr) {
+ return Nothing();
+ }
+
+ std::any result = TIdentifierVisitor().visit(ctx);
+ if (!result.has_value()) {
+ return Nothing();
+ }
+ return std::any_cast<TString>(result);
+ }
+
+ class TInferenceVisitor: public SQLv1Antlr4BaseVisitor {
+ public:
+ std::any visitTable_ref(SQLv1::Table_refContext* ctx) override {
+ TString cluster = GetId(ctx->cluster_expr()).GetOrElse("");
+
+ TMaybe<TString> path = GetId(ctx->table_key());
+ if (path.Empty()) {
+ return {};
+ }
+
+ return TColumnContext{
+ .Tables = {
+ {.Cluster = std::move(cluster), .Path = std::move(*path)},
+ },
+ };
+ }
+ };
+
+ class TVisitor: public TSQLv1NarrowingVisitor {
+ public:
+ TVisitor(antlr4::TokenStream* tokens, size_t cursorPosition)
+ : TSQLv1NarrowingVisitor(tokens, cursorPosition)
+ {
+ }
+
+ std::any visitSql_stmt_core(SQLv1::Sql_stmt_coreContext* ctx) override {
+ if (IsEnclosing(ctx)) {
+ return visitChildren(ctx);
+ }
+ return {};
+ }
+
+ std::any visitSelect_core(SQLv1::Select_coreContext* ctx) override {
+ SQLv1::Join_sourceContext* source = ctx->join_source(0);
+ if (source == nullptr) {
+ source = ctx->join_source(1);
+ }
+ if (source == nullptr) {
+ return {};
+ }
+
+ return TInferenceVisitor().visit(ctx);
+ }
+ };
+
+ } // namespace
+
+ TMaybe<TColumnContext> InferColumnContext(
+ SQLv1::Sql_queryContext* ctx,
+ antlr4::TokenStream* tokens,
+ size_t cursorPosition) {
+ // TODO: add utility `auto ToMaybe<T>(std::any any) -> TMaybe<T>`
+ std::any result = TVisitor(tokens, cursorPosition).visit(ctx);
+ if (!result.has_value()) {
+ return Nothing();
+ }
+ return std::any_cast<TColumnContext>(result);
+ }
+
+} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/analysis/global/column.h b/yql/essentials/sql/v1/complete/analysis/global/column.h
new file mode 100644
index 00000000000..790dbee1d15
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/analysis/global/column.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#include "global.h"
+#include "parse_tree.h"
+
+namespace NSQLComplete {
+
+ TMaybe<TColumnContext> InferColumnContext(
+ SQLv1::Sql_queryContext* ctx,
+ antlr4::TokenStream* tokens,
+ size_t cursorPosition);
+
+} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/analysis/global/global.cpp b/yql/essentials/sql/v1/complete/analysis/global/global.cpp
index 8f5df3f6e76..7574b6bdfc0 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/global.cpp
+++ b/yql/essentials/sql/v1/complete/analysis/global/global.cpp
@@ -1,5 +1,6 @@
#include "global.h"
+#include "column.h"
#include "function.h"
#include "named_node.h"
#include "parse_tree.h"
@@ -8,6 +9,10 @@
#include <yql/essentials/sql/v1/complete/antlr4/pipeline.h>
#include <yql/essentials/sql/v1/complete/syntax/ansi.h>
+#include <library/cpp/iterator/functools.h>
+
+#include <util/string/join.h>
+
namespace NSQLComplete {
class TErrorStrategy: public antlr4::DefaultErrorStrategy {
@@ -54,6 +59,11 @@ namespace NSQLComplete {
ctx.Use = FindUseStatement(sqlQuery, &Tokens_, input.CursorPosition, env);
ctx.Names = CollectNamedNodes(sqlQuery, &Tokens_, input.CursorPosition);
ctx.EnclosingFunction = EnclosingFunction(sqlQuery, &Tokens_, input.CursorPosition);
+ ctx.Column = InferColumnContext(sqlQuery, &Tokens_, input.CursorPosition);
+
+ if (ctx.Use && ctx.Column) {
+ EnrichTableClusters(*ctx.Column, *ctx.Use);
+ }
return ctx;
}
@@ -67,6 +77,14 @@ namespace NSQLComplete {
return Parser_.sql_query();
}
+ void EnrichTableClusters(TColumnContext& column, const TUseContext& use) {
+ for (auto& table : column.Tables) {
+ if (table.Cluster.empty()) {
+ table.Cluster = use.Cluster;
+ }
+ }
+ }
+
antlr4::ANTLRInputStream Chars_;
G::TLexer Lexer_;
antlr4::CommonTokenStream Tokens_;
@@ -97,3 +115,10 @@ namespace NSQLComplete {
}
} // namespace NSQLComplete
+
+template <>
+void Out<NSQLComplete::TColumnContext>(IOutputStream& out, const NSQLComplete::TColumnContext& value) {
+ out << "TColumnContext { ";
+ out << "Tables: " << JoinSeq(", ", value.Tables);
+ out << " }";
+}
diff --git a/yql/essentials/sql/v1/complete/analysis/global/global.h b/yql/essentials/sql/v1/complete/analysis/global/global.h
index 3999aeb4a56..1ef1344e3c9 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/global.h
+++ b/yql/essentials/sql/v1/complete/analysis/global/global.h
@@ -1,7 +1,8 @@
#pragma once
-#include <yql/essentials/sql/v1/complete/core/input.h>
#include <yql/essentials/sql/v1/complete/core/environment.h>
+#include <yql/essentials/sql/v1/complete/core/input.h>
+#include <yql/essentials/sql/v1/complete/core/name.h>
#include <util/generic/ptr.h>
#include <util/generic/maybe.h>
@@ -15,12 +16,20 @@ namespace NSQLComplete {
TString Cluster;
};
+ struct TColumnContext {
+ TVector<TTableId> Tables;
+
+ friend bool operator==(const TColumnContext& lhs, const TColumnContext& rhs) = default;
+ };
+
struct TGlobalContext {
TMaybe<TUseContext> Use;
TVector<TString> Names;
TMaybe<TString> EnclosingFunction;
+ TMaybe<TColumnContext> Column;
};
+ // TODO(YQL-19747): Make it thread-safe to make ISqlCompletionEngine thread-safe.
class IGlobalAnalysis {
public:
using TPtr = THolder<IGlobalAnalysis>;
diff --git a/yql/essentials/sql/v1/complete/analysis/global/global_ut.cpp b/yql/essentials/sql/v1/complete/analysis/global/global_ut.cpp
index 58aea33b379..c8222580cce 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/global_ut.cpp
+++ b/yql/essentials/sql/v1/complete/analysis/global/global_ut.cpp
@@ -98,4 +98,24 @@ Y_UNIT_TEST_SUITE(GlobalAnalysisTests) {
}
}
+ Y_UNIT_TEST(SimpleSelectFrom) {
+ IGlobalAnalysis::TPtr global = MakeGlobalAnalysis();
+ {
+ TString query = "SELECT # FROM plato.Input";
+
+ TGlobalContext ctx = global->Analyze(SharpedInput(query), {});
+
+ TColumnContext expected = {.Tables = {{"plato", "Input"}}};
+ UNIT_ASSERT_VALUES_EQUAL(ctx.Column, expected);
+ }
+ {
+ TString query = "SELECT # FROM plato.`//home/input`";
+
+ TGlobalContext ctx = global->Analyze(SharpedInput(query), {});
+
+ TColumnContext expected = {.Tables = {{"plato", "//home/input"}}};
+ UNIT_ASSERT_VALUES_EQUAL(ctx.Column, expected);
+ }
+ }
+
} // Y_UNIT_TEST_SUITE(GlobalAnalysisTests)
diff --git a/yql/essentials/sql/v1/complete/analysis/global/ya.make b/yql/essentials/sql/v1/complete/analysis/global/ya.make
index b37fa3faa22..1f1670a9675 100644
--- a/yql/essentials/sql/v1/complete/analysis/global/ya.make
+++ b/yql/essentials/sql/v1/complete/analysis/global/ya.make
@@ -1,6 +1,7 @@
LIBRARY()
SRCS(
+ column.cpp
evaluate.cpp
function.cpp
global.cpp
diff --git a/yql/essentials/sql/v1/complete/analysis/local/local.cpp b/yql/essentials/sql/v1/complete/analysis/local/local.cpp
index b7e97b51e59..13e2fce69ad 100644
--- a/yql/essentials/sql/v1/complete/analysis/local/local.cpp
+++ b/yql/essentials/sql/v1/complete/analysis/local/local.cpp
@@ -51,10 +51,13 @@ namespace NSQLComplete {
public:
TSpecializedLocalSyntaxAnalysis(
- TLexerSupplier lexer, const THashSet<TString>& IgnoredRules)
+ TLexerSupplier lexer,
+ const THashSet<TString>& ignoredRules,
+ const THashMap<TString, THashSet<TString>>& disabledPreviousByToken,
+ const THashMap<TString, THashSet<TString>>& forcedPreviousByToken)
: Grammar_(&GetSqlGrammar())
, Lexer_(lexer(/* ansi = */ IsAnsiLexer))
- , C3_(ComputeC3Config(IgnoredRules))
+ , C3_(ComputeC3Config(ignoredRules, disabledPreviousByToken, forcedPreviousByToken))
{
}
@@ -104,17 +107,23 @@ namespace NSQLComplete {
result.Hint = HintMatch(candidates);
result.Object = ObjectMatch(context, candidates);
result.Cluster = ClusterMatch(context, candidates);
+ result.Column = ColumnMatch(candidates);
result.Binding = BindingMatch(candidates);
return result;
}
private:
- IC3Engine::TConfig ComputeC3Config(const THashSet<TString>& IgnoredRules) const {
+ IC3Engine::TConfig ComputeC3Config(
+ const THashSet<TString>& ignoredRules,
+ const THashMap<TString, THashSet<TString>>& disabledPreviousByToken,
+ const THashMap<TString, THashSet<TString>>& forcedPreviousByToken) const {
return {
.IgnoredTokens = ComputeIgnoredTokens(),
.PreferredRules = ComputePreferredRules(),
- .IgnoredRules = ComputeIgnoredRules(IgnoredRules),
+ .IgnoredRules = ComputeIgnoredRules(ignoredRules),
+ .DisabledPreviousByToken = Resolved(disabledPreviousByToken),
+ .ForcedPreviousByToken = Resolved(forcedPreviousByToken),
};
}
@@ -142,6 +151,23 @@ namespace NSQLComplete {
return ignored;
}
+ std::unordered_map<TTokenId, std::unordered_set<TTokenId>>
+ Resolved(const THashMap<TString, THashSet<TString>>& tokens) const {
+ std::unordered_map<TTokenId, std::unordered_set<TTokenId>> resolved;
+ for (const auto& [name, set] : tokens) {
+ resolved[Grammar_->GetTokenId(name)] = Resolved(set);
+ }
+ return resolved;
+ }
+
+ std::unordered_set<TTokenId> Resolved(const THashSet<TString>& tokens) const {
+ std::unordered_set<TTokenId> resolved;
+ for (const TString& name : tokens) {
+ resolved.emplace(Grammar_->GetTokenId(name));
+ }
+ return resolved;
+ }
+
TC3Candidates C3Complete(TCompletionInput statement, const TCursorTokenContext& context) {
auto enclosing = context.Enclosing();
@@ -296,6 +322,10 @@ namespace NSQLComplete {
return cluster;
}
+ bool ColumnMatch(const TC3Candidates& candidates) const {
+ return AnyOf(candidates.Rules, RuleAdapted(IsLikelyColumnStack));
+ }
+
bool BindingMatch(const TC3Candidates& candidates) const {
return AnyOf(candidates.Rules, RuleAdapted(IsLikelyBindingStack));
}
@@ -331,9 +361,12 @@ namespace NSQLComplete {
class TLocalSyntaxAnalysis: public ILocalSyntaxAnalysis {
public:
TLocalSyntaxAnalysis(
- TLexerSupplier lexer, const THashSet<TString>& IgnoredRules)
- : DefaultEngine_(lexer, IgnoredRules)
- , AnsiEngine_(lexer, IgnoredRules)
+ TLexerSupplier lexer,
+ const THashSet<TString>& ignoredRules,
+ const THashMap<TString, THashSet<TString>>& disabledPreviousByToken,
+ const THashMap<TString, THashSet<TString>>& forcedPreviousByToken)
+ : DefaultEngine_(lexer, ignoredRules, disabledPreviousByToken, forcedPreviousByToken)
+ , AnsiEngine_(lexer, ignoredRules, disabledPreviousByToken, forcedPreviousByToken)
{
}
@@ -356,8 +389,11 @@ namespace NSQLComplete {
};
ILocalSyntaxAnalysis::TPtr MakeLocalSyntaxAnalysis(
- TLexerSupplier lexer, const THashSet<TString>& IgnoredRules) {
- return MakeHolder<TLocalSyntaxAnalysis>(lexer, IgnoredRules);
+ TLexerSupplier lexer,
+ const THashSet<TString>& ignoredRules,
+ const THashMap<TString, THashSet<TString>>& disabledPreviousByToken,
+ const THashMap<TString, THashSet<TString>>& forcedPreviousByToken) {
+ return MakeHolder<TLocalSyntaxAnalysis>(lexer, ignoredRules, disabledPreviousByToken, forcedPreviousByToken);
}
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/analysis/local/local.h b/yql/essentials/sql/v1/complete/analysis/local/local.h
index 5557d6b6dc0..cca182aacdb 100644
--- a/yql/essentials/sql/v1/complete/analysis/local/local.h
+++ b/yql/essentials/sql/v1/complete/analysis/local/local.h
@@ -55,10 +55,12 @@ namespace NSQLComplete {
TMaybe<THint> Hint;
TMaybe<TObject> Object;
TMaybe<TCluster> Cluster;
+ bool Column = false;
bool Binding = false;
TEditRange EditRange;
};
+ // TODO(YQL-19747): Make it thread-safe to make ISqlCompletionEngine thread-safe.
class ILocalSyntaxAnalysis {
public:
using TPtr = THolder<ILocalSyntaxAnalysis>;
@@ -68,6 +70,9 @@ namespace NSQLComplete {
};
ILocalSyntaxAnalysis::TPtr MakeLocalSyntaxAnalysis(
- TLexerSupplier lexer, const THashSet<TString>& IgnoredRules);
+ TLexerSupplier lexer,
+ const THashSet<TString>& ignoredRules,
+ const THashMap<TString, THashSet<TString>>& disabledPreviousByToken,
+ const THashMap<TString, THashSet<TString>>& forcedPreviousByToken);
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/analysis/local/parser_call_stack.cpp b/yql/essentials/sql/v1/complete/analysis/local/parser_call_stack.cpp
index 293cb333d5c..8ac4ff17999 100644
--- a/yql/essentials/sql/v1/complete/analysis/local/parser_call_stack.cpp
+++ b/yql/essentials/sql/v1/complete/analysis/local/parser_call_stack.cpp
@@ -33,6 +33,9 @@ namespace NSQLComplete {
RULE(Id_hint),
RULE(Opt_id_prefix_or_type),
RULE(Type_name_simple),
+ RULE(Type_name_composite),
+ RULE(Type_name_decimal),
+ RULE(Value_constructor),
};
TVector<std::string> Symbolized(const TParserCallStack& stack) {
@@ -69,6 +72,8 @@ namespace NSQLComplete {
bool IsLikelyTypeStack(const TParserCallStack& stack) {
return EndsWith({RULE(Type_name_simple)}, stack) ||
+ EndsWith({RULE(Type_name_composite)}, stack) ||
+ EndsWith({RULE(Type_name_decimal)}, stack) ||
(Contains({RULE(Invoke_expr),
RULE(Named_expr_list),
RULE(Named_expr),
@@ -89,7 +94,8 @@ namespace NSQLComplete {
RULE(Atom_expr),
RULE(Bind_parameter),
RULE(An_id_or_type)}, stack) ||
- EndsWith({RULE(Atom_expr), RULE(Id_or_type)}, stack);
+ EndsWith({RULE(Atom_expr), RULE(Id_or_type)}, stack) ||
+ EndsWith({RULE(Value_constructor)}, stack);
}
bool IsLikelyHintStack(const TParserCallStack& stack) {
@@ -117,6 +123,10 @@ namespace NSQLComplete {
return Contains({RULE(Cluster_expr)}, stack);
}
+ bool IsLikelyColumnStack(const TParserCallStack& stack) {
+ return Contains({RULE(Result_column)}, stack);
+ }
+
bool IsLikelyBindingStack(const TParserCallStack& stack) {
return EndsWith({RULE(Bind_parameter), RULE(An_id_or_type)}, stack);
}
diff --git a/yql/essentials/sql/v1/complete/analysis/local/parser_call_stack.h b/yql/essentials/sql/v1/complete/analysis/local/parser_call_stack.h
index c8daf9114fe..a0c479a8be0 100644
--- a/yql/essentials/sql/v1/complete/analysis/local/parser_call_stack.h
+++ b/yql/essentials/sql/v1/complete/analysis/local/parser_call_stack.h
@@ -21,6 +21,8 @@ namespace NSQLComplete {
bool IsLikelyClusterStack(const TParserCallStack& stack);
+ bool IsLikelyColumnStack(const TParserCallStack& stack);
+
bool IsLikelyBindingStack(const TParserCallStack& stack);
TMaybe<EStatementKind> StatementKindOf(const TParserCallStack& stack);
diff --git a/yql/essentials/sql/v1/complete/antlr4/c3i.h b/yql/essentials/sql/v1/complete/antlr4/c3i.h
index 52920882ee0..b3fcaab7ae0 100644
--- a/yql/essentials/sql/v1/complete/antlr4/c3i.h
+++ b/yql/essentials/sql/v1/complete/antlr4/c3i.h
@@ -37,6 +37,8 @@ namespace NSQLComplete {
std::unordered_set<TTokenId> IgnoredTokens;
std::unordered_set<TRuleId> PreferredRules;
std::unordered_set<TRuleId> IgnoredRules;
+ std::unordered_map<TTokenId, std::unordered_set<TTokenId>> DisabledPreviousByToken;
+ std::unordered_map<TTokenId, std::unordered_set<TTokenId>> ForcedPreviousByToken;
};
virtual ~IC3Engine() = default;
diff --git a/yql/essentials/sql/v1/complete/antlr4/c3t.h b/yql/essentials/sql/v1/complete/antlr4/c3t.h
index 2b49068ac8f..d1c80867a59 100644
--- a/yql/essentials/sql/v1/complete/antlr4/c3t.h
+++ b/yql/essentials/sql/v1/complete/antlr4/c3t.h
@@ -13,6 +13,7 @@
#include <util/generic/fwd.h>
#include <util/generic/string.h>
#include <util/generic/vector.h>
+#include <util/generic/yexception.h>
namespace NSQLComplete {
@@ -26,6 +27,8 @@ namespace NSQLComplete {
, Parser_(&Tokens_)
, CompletionCore_(&Parser_)
, IgnoredRules_(std::move(config.IgnoredRules))
+ , DisabledPreviousByToken_(std::move(config.DisabledPreviousByToken))
+ , ForcedPreviousByToken_(std::move(config.ForcedPreviousByToken))
{
Lexer_.removeErrorListeners();
Parser_.removeErrorListeners();
@@ -36,15 +39,29 @@ namespace NSQLComplete {
for (TRuleId rule : IgnoredRules_) {
CompletionCore_.preferredRules.emplace(rule);
}
+
+ PurifyForcedTokens();
}
TC3Candidates Complete(TStringBuf text, size_t caretTokenIndex) override {
Assign(text);
auto candidates = CompletionCore_.collectCandidates(caretTokenIndex);
- return Converted(std::move(candidates));
+ return Converted(std::move(candidates), caretTokenIndex);
}
private:
+ void PurifyForcedTokens() {
+ for (auto it = ForcedPreviousByToken_.begin(); it != ForcedPreviousByToken_.end();) {
+ const auto& [token, previous] = *it;
+ if (previous.empty()) {
+ CompletionCore_.ignoredTokens.emplace(token);
+ it = ForcedPreviousByToken_.erase(it);
+ } else {
+ it = std::next(it);
+ }
+ }
+ }
+
void Assign(TStringBuf prefix) {
Chars_.load(prefix.Data(), prefix.Size(), /* lenient = */ false);
Lexer_.reset();
@@ -52,10 +69,14 @@ namespace NSQLComplete {
Tokens_.fill();
}
- TC3Candidates Converted(c3::CandidatesCollection candidates) const {
+ TC3Candidates Converted(c3::CandidatesCollection candidates, size_t caretTokenIndex) {
TC3Candidates converted;
for (auto& [token, following] : candidates.tokens) {
+ if (IsIgnored(token, caretTokenIndex)) {
+ continue;
+ }
+
converted.Tokens.emplace_back(token, std::move(following));
}
@@ -71,17 +92,43 @@ namespace NSQLComplete {
return converted;
}
+ bool IsIgnored(TTokenId token, size_t caretTokenIndex) {
+ auto previous = PreviousToken(caretTokenIndex);
+
+ auto disabled = DisabledPreviousByToken_.find(token);
+ auto forced = ForcedPreviousByToken_.find(token);
+
+ return (disabled != DisabledPreviousByToken_.end() && disabled->second.contains(previous)) ||
+ (forced != ForcedPreviousByToken_.end() && !forced->second.contains(previous));
+ }
+
bool IsIgnored(TRuleId head, const std::vector<TRuleId> tail) const {
return IgnoredRules_.contains(head) ||
AnyOf(tail, [this](TRuleId r) { return IgnoredRules_.contains(r); });
}
+ TTokenId PreviousToken(size_t caretTokenIndex) {
+ ssize_t index = static_cast<ssize_t>(caretTokenIndex) - 1;
+ while (0 <= index && Tokens_.get(index)->getChannel() == antlr4::Token::HIDDEN_CHANNEL) {
+ --index;
+ }
+
+ if (index < 0) {
+ return antlr4::Token::INVALID_TYPE;
+ }
+
+ return Tokens_.get(index)->getType();
+ }
+
antlr4::ANTLRInputStream Chars_;
G::TLexer Lexer_;
antlr4::BufferedTokenStream Tokens_;
G::TParser Parser_;
c3::CodeCompletionCore CompletionCore_;
+
std::unordered_set<TRuleId> IgnoredRules_;
+ std::unordered_map<TTokenId, std::unordered_set<TTokenId>> DisabledPreviousByToken_;
+ std::unordered_map<TTokenId, std::unordered_set<TTokenId>> ForcedPreviousByToken_;
};
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/core/name.cpp b/yql/essentials/sql/v1/complete/core/name.cpp
new file mode 100644
index 00000000000..65c28e51176
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/core/name.cpp
@@ -0,0 +1,8 @@
+#include "name.h"
+
+#include <util/stream/output.h>
+
+template <>
+void Out<NSQLComplete::TTableId>(IOutputStream& out, const NSQLComplete::TTableId& value) {
+ out << value.Cluster << ".`" << value.Path << "`";
+}
diff --git a/yql/essentials/sql/v1/complete/core/name.h b/yql/essentials/sql/v1/complete/core/name.h
index 02524766de1..3eac47f3871 100644
--- a/yql/essentials/sql/v1/complete/core/name.h
+++ b/yql/essentials/sql/v1/complete/core/name.h
@@ -1,5 +1,7 @@
#pragma once
+#include <util/generic/string.h>
+
namespace NSQLComplete {
enum class EObjectKind {
@@ -7,4 +9,11 @@ namespace NSQLComplete {
Table,
};
+ struct TTableId {
+ TString Cluster;
+ TString Path;
+
+ friend bool operator==(const TTableId& lhs, const TTableId& rhs) = default;
+ };
+
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/core/statement.cpp b/yql/essentials/sql/v1/complete/core/statement.cpp
new file mode 100644
index 00000000000..c93e5a7f803
--- /dev/null
+++ b/yql/essentials/sql/v1/complete/core/statement.cpp
@@ -0,0 +1 @@
+#include "statement.h"
diff --git a/yql/essentials/sql/v1/complete/core/ya.make b/yql/essentials/sql/v1/complete/core/ya.make
index 599810301ca..0cd0776b11e 100644
--- a/yql/essentials/sql/v1/complete/core/ya.make
+++ b/yql/essentials/sql/v1/complete/core/ya.make
@@ -3,6 +3,8 @@ LIBRARY()
SRCS(
environment.cpp
input.cpp
+ name.cpp
+ statement.cpp
)
PEERDIR(
diff --git a/yql/essentials/sql/v1/complete/name/object/schema.h b/yql/essentials/sql/v1/complete/name/object/schema.h
index b9aa720d36f..d779b293674 100644
--- a/yql/essentials/sql/v1/complete/name/object/schema.h
+++ b/yql/essentials/sql/v1/complete/name/object/schema.h
@@ -41,12 +41,26 @@ namespace NSQLComplete {
TVector<TFolderEntry> Entries;
};
+ struct TDescribeTableRequest {
+ TString TableCluster;
+ TString TablePath;
+ TString ColumnPrefix;
+ size_t ColumnsLimit = 128; // TODO: introduce default limit constant
+ };
+
+ struct TDescribeTableResponse {
+ bool IsExisting = false;
+ TVector<TString> Columns;
+ };
+
class ISchema: public TThrRefBase {
public:
using TPtr = TIntrusivePtr<ISchema>;
- ~ISchema() override = default;
virtual NThreading::TFuture<TListResponse> List(const TListRequest& request) const = 0;
+
+ virtual NThreading::TFuture<TDescribeTableResponse>
+ Describe(const TDescribeTableRequest& request) const = 0;
};
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/name/object/simple/schema.cpp b/yql/essentials/sql/v1/complete/name/object/simple/schema.cpp
index a9dd20ada99..043464bd73e 100644
--- a/yql/essentials/sql/v1/complete/name/object/simple/schema.cpp
+++ b/yql/essentials/sql/v1/complete/name/object/simple/schema.cpp
@@ -8,7 +8,7 @@ namespace NSQLComplete {
class TSimpleSchema: public ISchema {
private:
- static auto FilterByName(TString name) {
+ static auto FilterEntriesByName(TString name) {
return [name = std::move(name)](auto f) {
TVector<TFolderEntry> entries = f.ExtractValue();
EraseIf(entries, [prefix = ToLowerUTF8(name)](const TFolderEntry& entry) {
@@ -18,7 +18,7 @@ namespace NSQLComplete {
};
}
- static auto FilterByTypes(TMaybe<THashSet<TString>> types) {
+ static auto FilterEntriesByTypes(TMaybe<THashSet<TString>> types) {
return [types = std::move(types)](auto f) mutable {
TVector<TFolderEntry> entries = f.ExtractValue();
EraseIf(entries, [types = std::move(types)](const TFolderEntry& entry) {
@@ -28,7 +28,7 @@ namespace NSQLComplete {
};
}
- static auto Crop(size_t limit) {
+ static auto CropEntries(size_t limit) {
return [limit](auto f) {
TVector<TFolderEntry> entries = f.ExtractValue();
entries.crop(limit);
@@ -36,7 +36,7 @@ namespace NSQLComplete {
};
}
- static auto ToResponse(TStringBuf name) {
+ static auto ToListResponse(TStringBuf name) {
const auto length = name.length();
return [length](auto f) {
return TListResponse{
@@ -46,6 +46,38 @@ namespace NSQLComplete {
};
}
+ static auto FilterColumnsByName(TString name) {
+ return [name = std::move(name)](auto f) {
+ return f.ExtractValue().Transform([&](auto&& table) {
+ EraseIf(table.Columns, [prefix = ToLowerUTF8(name)](const TString& name) {
+ return !name.StartsWith(prefix);
+ });
+ return table;
+ });
+ };
+ }
+
+ static auto CropColumns(size_t limit) {
+ return [limit](auto f) {
+ return f.ExtractValue().Transform([&](auto&& table) {
+ table.Columns.crop(limit);
+ return table;
+ });
+ };
+ }
+
+ static auto ToTableDescribeResponse() {
+ return [](auto f) {
+ TMaybe<TTableDetails> table = f.ExtractValue();
+ return TDescribeTableResponse{
+ .IsExisting = table.Defined(),
+ .Columns = table
+ .Transform([](auto&& table) { return table.Columns; })
+ .GetOrElse({}),
+ };
+ };
+ }
+
public:
explicit TSimpleSchema(ISimpleSchema::TPtr simple)
: Simple_(std::move(simple))
@@ -55,10 +87,19 @@ namespace NSQLComplete {
NThreading::TFuture<TListResponse> List(const TListRequest& request) const override {
auto [path, name] = Simple_->Split(request.Path);
return Simple_->List(request.Cluster, TString(path))
- .Apply(FilterByName(TString(name)))
- .Apply(FilterByTypes(request.Filter.Types))
- .Apply(Crop(request.Limit))
- .Apply(ToResponse(name));
+ .Apply(FilterEntriesByName(TString(name)))
+ .Apply(FilterEntriesByTypes(request.Filter.Types))
+ .Apply(CropEntries(request.Limit))
+ .Apply(ToListResponse(name));
+ }
+
+ NThreading::TFuture<TDescribeTableResponse>
+ Describe(const TDescribeTableRequest& request) const override {
+ return Simple_
+ ->DescribeTable(request.TableCluster, request.TablePath)
+ .Apply(FilterColumnsByName(TString(request.ColumnPrefix)))
+ .Apply(CropColumns(request.ColumnsLimit))
+ .Apply(ToTableDescribeResponse());
}
private:
@@ -77,6 +118,12 @@ namespace NSQLComplete {
return List(std::move(folder));
}
+ NThreading::TFuture<TMaybe<TTableDetails>>
+ ISimpleSchema::DescribeTable(const TString& cluster, const TString& path) const {
+ Y_UNUSED(cluster, path);
+ return NThreading::MakeFuture<TMaybe<TTableDetails>>(Nothing());
+ }
+
ISchema::TPtr MakeSimpleSchema(ISimpleSchema::TPtr simple) {
return ISchema::TPtr(new TSimpleSchema(std::move(simple)));
}
diff --git a/yql/essentials/sql/v1/complete/name/object/simple/schema.h b/yql/essentials/sql/v1/complete/name/object/simple/schema.h
index e3b5cb4cb1b..2bdb428b191 100644
--- a/yql/essentials/sql/v1/complete/name/object/simple/schema.h
+++ b/yql/essentials/sql/v1/complete/name/object/simple/schema.h
@@ -9,6 +9,10 @@ namespace NSQLComplete {
TStringBuf NameHint;
};
+ struct TTableDetails {
+ TVector<TString> Columns;
+ };
+
class ISimpleSchema: public TThrRefBase {
public:
using TPtr = TIntrusivePtr<ISimpleSchema>;
@@ -22,6 +26,9 @@ namespace NSQLComplete {
virtual NThreading::TFuture<TVector<TFolderEntry>>
List(TString cluster, TString folder) const;
+
+ virtual NThreading::TFuture<TMaybe<TTableDetails>>
+ DescribeTable(const TString& cluster, const TString& path) const;
};
ISchema::TPtr MakeSimpleSchema(ISimpleSchema::TPtr simple);
diff --git a/yql/essentials/sql/v1/complete/name/object/simple/static/schema.cpp b/yql/essentials/sql/v1/complete/name/object/simple/static/schema.cpp
index 3482da8a332..7707d8dc4ba 100644
--- a/yql/essentials/sql/v1/complete/name/object/simple/static/schema.cpp
+++ b/yql/essentials/sql/v1/complete/name/object/simple/static/schema.cpp
@@ -1,20 +1,32 @@
#include "schema.h"
+#include <library/cpp/iterator/concatenate.h>
+
namespace NSQLComplete {
namespace {
class TSimpleSchema: public ISimpleSchema {
public:
- explicit TSimpleSchema(THashMap<TString, THashMap<TString, TVector<TFolderEntry>>> data)
- : Data_(std::move(data))
+ explicit TSimpleSchema(
+ THashMap<TString, THashMap<TString, TVector<TFolderEntry>>> folders,
+ THashMap<TString, THashMap<TString, TTableDetails>> tables)
+ : Folders_(std::move(folders))
+ , Tables_(std::move(tables))
{
- for (const auto& [_, tables] : Data_) {
- for (const auto& [k, _] : tables) {
+ for (const auto& [_, paths] : Folders_) {
+ for (const auto& [k, _] : paths) {
Y_ENSURE(k.StartsWith("/"), k << " must start with the '/'");
Y_ENSURE(k.EndsWith("/"), k << " must end with the '/'");
}
}
+
+ for (const auto& [_, paths] : Tables_) {
+ for (const auto& [k, _] : paths) {
+ Y_ENSURE(k.StartsWith("/"), k << " must start with the '/'");
+ Y_ENSURE(!k.EndsWith("/"), k << " must not end with the '/'");
+ }
+ }
}
TSplittedPath Split(TStringBuf path) const override {
@@ -37,7 +49,7 @@ namespace NSQLComplete {
const THashMap<TString, TVector<TFolderEntry>>* tables = nullptr;
const TVector<TFolderEntry>* items = nullptr;
- if ((tables = Data_.FindPtr(cluster)) &&
+ if ((tables = Folders_.FindPtr(cluster)) &&
(items = tables->FindPtr(folder))) {
entries = *items;
}
@@ -45,15 +57,32 @@ namespace NSQLComplete {
return NThreading::MakeFuture(std::move(entries));
}
+ NThreading::TFuture<TMaybe<TTableDetails>>
+ DescribeTable(const TString& cluster, const TString& path) const override {
+ auto* tables = Tables_.FindPtr(cluster);
+ if (tables == nullptr) {
+ return NThreading::MakeFuture<TMaybe<TTableDetails>>(Nothing());
+ }
+
+ auto* details = tables->FindPtr(path);
+ if (details == nullptr) {
+ return NThreading::MakeFuture<TMaybe<TTableDetails>>(Nothing());
+ }
+
+ return NThreading::MakeFuture<TMaybe<TTableDetails>>(*details);
+ }
+
private:
- THashMap<TString, THashMap<TString, TVector<TFolderEntry>>> Data_;
+ THashMap<TString, THashMap<TString, TVector<TFolderEntry>>> Folders_;
+ THashMap<TString, THashMap<TString, TTableDetails>> Tables_;
};
} // namespace
ISimpleSchema::TPtr MakeStaticSimpleSchema(
- THashMap<TString, THashMap<TString, TVector<TFolderEntry>>> fs) {
- return new TSimpleSchema(std::move(fs));
+ THashMap<TString, THashMap<TString, TVector<TFolderEntry>>> folders,
+ THashMap<TString, THashMap<TString, TTableDetails>> tables) {
+ return new TSimpleSchema(std::move(folders), std::move(tables));
}
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/name/object/simple/static/schema.h b/yql/essentials/sql/v1/complete/name/object/simple/static/schema.h
index 009b433ee4a..57fb322d6e2 100644
--- a/yql/essentials/sql/v1/complete/name/object/simple/static/schema.h
+++ b/yql/essentials/sql/v1/complete/name/object/simple/static/schema.h
@@ -5,6 +5,7 @@
namespace NSQLComplete {
ISimpleSchema::TPtr MakeStaticSimpleSchema(
- THashMap<TString, THashMap<TString, TVector<TFolderEntry>>> fs);
+ THashMap<TString, THashMap<TString, TVector<TFolderEntry>>> folders,
+ THashMap<TString, THashMap<TString, TTableDetails>> tables = {});
} // namespace NSQLComplete
diff --git a/yql/essentials/sql/v1/complete/name/service/name_service.h b/yql/essentials/sql/v1/complete/name/service/name_service.h
index 2095cb35335..5139b27dfa3 100644
--- a/yql/essentials/sql/v1/complete/name/service/name_service.h
+++ b/yql/essentials/sql/v1/complete/name/service/name_service.h
@@ -30,6 +30,14 @@ namespace NSQLComplete {
struct TTypeName: TIndentifier {
struct TConstraints {};
+
+ enum class EKind {
+ Simple,
+ Container,
+ Parameterized,
+ };
+
+ EKind Kind = EKind::Simple;
};
struct TFunctionName: TIndentifier {
@@ -58,6 +66,12 @@ namespace NSQLComplete {
struct TConstraints: TNamespaced {};
};
+ struct TColumnName: TIndentifier {
+ struct TConstraints {
+ TVector<TTableId> Tables;
+ };
+ };
+
struct TBindingName: TIndentifier {
};
@@ -75,6 +89,7 @@ namespace NSQLComplete {
TFolderName,
TTableName,
TClusterName,
+ TColumnName,
TBindingName,
TUnkownName>;
@@ -85,6 +100,7 @@ namespace NSQLComplete {
TMaybe<THintName::TConstraints> Hint;
TMaybe<TObjectNameConstraints> Object;
TMaybe<TClusterName::TConstraints> Cluster;
+ TMaybe<TColumnName::TConstraints> Column;
bool IsEmpty() const {
return !Pragma &&
@@ -92,7 +108,8 @@ namespace NSQLComplete {
!Function &&
!Hint &&
!Object &&
- !Cluster;
+ !Cluster &&
+ !Column;
}
TGenericName Qualified(TGenericName unqualified) const;
diff --git a/yql/essentials/sql/v1/complete/name/service/ranking/ranking.cpp b/yql/essentials/sql/v1/complete/name/service/ranking/ranking.cpp
index 9f30ead37d5..d8e0e0ff1bb 100644
--- a/yql/essentials/sql/v1/complete/name/service/ranking/ranking.cpp
+++ b/yql/essentials/sql/v1/complete/name/service/ranking/ranking.cpp
@@ -92,7 +92,8 @@ namespace NSQLComplete {
}
if constexpr (std::is_same_v<T, TFolderName> ||
- std::is_same_v<T, TTableName>) {
+ std::is_same_v<T, TTableName> ||
+ std::is_same_v<T, TColumnName>) {
return std::numeric_limits<size_t>::max();
}
diff --git a/yql/essentials/sql/v1/complete/name/service/schema/name_service.cpp b/yql/essentials/sql/v1/complete/name/service/schema/name_service.cpp
index b21ad828317..2970f06d7cd 100644
--- a/yql/essentials/sql/v1/complete/name/service/schema/name_service.cpp
+++ b/yql/essentials/sql/v1/complete/name/service/schema/name_service.cpp
@@ -12,13 +12,26 @@ namespace NSQLComplete {
}
NThreading::TFuture<TNameResponse> Lookup(TNameRequest request) const override {
- if (!request.Constraints.Object) {
- return NThreading::MakeFuture<TNameResponse>({});
+ if (request.Constraints.Object) {
+ return Schema_
+ ->List(ToListRequest(std::move(request)))
+ .Apply(ToListNameResponse);
}
- return Schema_
- ->List(ToListRequest(std::move(request)))
- .Apply(ToNameResponse);
+ if (request.Constraints.Column) {
+ Y_ENSURE(request.Constraints.Column->Tables.size() == 1, "Not Implemented");
+ TTableId table = request.Constraints.Column->Tables[0];
+ return Schema_
+ ->Describe({
+ .TableCluster = table.Cluster,
+ .TablePath = table.Path,
+ .ColumnPrefix = request.Prefix,
+ .ColumnsLimit = request.Limit,
+ })
+ .Apply(ToDescribeNameResponse);
+ }
+
+ return NThreading::MakeFuture<TNameResponse>({});
}
private:
@@ -53,7 +66,7 @@ namespace NSQLComplete {
}
}
- static TNameResponse ToNameResponse(NThreading::TFuture<TListResponse> f) {
+ static TNameResponse ToListNameResponse(NThreading::TFuture<TListResponse> f) {
TListResponse list = f.ExtractValue();
TNameResponse response;
@@ -83,6 +96,18 @@ namespace NSQLComplete {
return name;
}
+ static TNameResponse ToDescribeNameResponse(NThreading::TFuture<TDescribeTableResponse> f) {
+ TDescribeTableResponse table = f.ExtractValue();
+
+ TNameResponse response;
+ for (TString& column : table.Columns) {
+ TColumnName name;
+ name.Indentifier = std::move(column);
+ response.RankedNames.emplace_back(std::move(name));
+ }
+ return response;
+ }
+
ISchema::TPtr Schema_;
};
diff --git a/yql/essentials/sql/v1/complete/name/service/static/name_service.cpp b/yql/essentials/sql/v1/complete/name/service/static/name_service.cpp
index b294953720f..ca3a66c2b0c 100644
--- a/yql/essentials/sql/v1/complete/name/service/static/name_service.cpp
+++ b/yql/essentials/sql/v1/complete/name/service/static/name_service.cpp
@@ -20,7 +20,18 @@ namespace NSQLComplete {
template <class T, class S = TStringBuf>
void AppendAs(TVector<TGenericName>& target, const TVector<S>& source) {
for (const auto& element : source) {
- target.emplace_back(T{TString(element)});
+ T name;
+
+ TString* content = nullptr;
+ if constexpr (std::is_same_v<TKeyword, T>) {
+ content = &name.Content;
+ } else {
+ content = &name.Indentifier;
+ }
+
+ *content = element;
+
+ target.emplace_back(std::move(name));
}
}
@@ -112,24 +123,54 @@ namespace NSQLComplete {
public:
TTypeNameService(IRanking::TPtr ranking, TVector<TString> types)
: IRankingNameService(std::move(ranking))
- , Types_(BuildNameIndex(std::move(types), NormalizeName))
+ , SimpleTypes_(BuildNameIndex(std::move(types), NormalizeName))
+ , ContainerTypes_(BuildNameIndex(
+ {
+ "Optional",
+ "Tuple",
+ "Struct",
+ "Variant",
+ "List",
+ "Stream",
+ "Flow",
+ "Dict",
+ "Set",
+ "Enum",
+ "Resource",
+ "Tagged",
+ "Callable",
+ }, NormalizeName))
+ , ParameterizedTypes_(BuildNameIndex(
+ {
+ "Decimal",
+ }, NormalizeName))
{
}
NThreading::TFuture<TNameResponse> LookupAllUnranked(TNameRequest request) const override {
TNameResponse response;
if (request.Constraints.Type) {
- NameIndexScan<TTypeName>(
- Types_,
- request.Prefix,
- request.Constraints,
- response.RankedNames);
+ NameIndexScan<TTypeName>(SimpleTypes_, request.Prefix, request.Constraints, response.RankedNames);
+
+ size_t previousSize = response.RankedNames.size();
+ NameIndexScan<TTypeName>(ContainerTypes_, request.Prefix, request.Constraints, response.RankedNames);
+ for (size_t i = previousSize; i < response.RankedNames.size(); ++i) {
+ std::get<TTypeName>(response.RankedNames[i]).Kind = TTypeName::EKind::Container;
+ }
+
+ previousSize = response.RankedNames.size();
+ NameIndexScan<TTypeName>(ParameterizedTypes_, request.Prefix, request.Constraints, response.RankedNames);
+ for (size_t i = previousSize; i < response.RankedNames.size(); ++i) {
+ std::get<TTypeName>(response.RankedNames[i]).Kind = TTypeName::EKind::Parameterized;
+ }
}
return NThreading::MakeFuture<TNameResponse>(std::move(response));
}
private:
- TNameIndex Types_;
+ TNameIndex SimpleTypes_;
+ TNameIndex ContainerTypes_;
+ TNameIndex ParameterizedTypes_;
};
class TFunctionNameService: public IRankingNameService {
diff --git a/yql/essentials/sql/v1/complete/sql_complete.cpp b/yql/essentials/sql/v1/complete/sql_complete.cpp
index 786155912c0..2ed153f3ecc 100644
--- a/yql/essentials/sql/v1/complete/sql_complete.cpp
+++ b/yql/essentials/sql/v1/complete/sql_complete.cpp
@@ -22,7 +22,11 @@ namespace NSQLComplete {
INameService::TPtr names,
ISqlCompletionEngine::TConfiguration configuration)
: Configuration_(std::move(configuration))
- , SyntaxAnalysis_(MakeLocalSyntaxAnalysis(lexer, Configuration_.IgnoredRules))
+ , SyntaxAnalysis_(MakeLocalSyntaxAnalysis(
+ lexer,
+ Configuration_.IgnoredRules,
+ Configuration_.DisabledPreviousByToken,
+ Configuration_.ForcedPreviousByToken))
, GlobalAnalysis_(MakeGlobalAnalysis())
, Names_(std::move(names))
{
@@ -142,6 +146,11 @@ namespace NSQLComplete {
object->Kinds.emplace(EObjectKind::Table);
}
+ if (context.Column && global.Column) {
+ request.Constraints.Column = TColumnName::TConstraints();
+ request.Constraints.Column->Tables = std::move(global.Column->Tables);
+ }
+
return request;
}
@@ -190,6 +199,16 @@ namespace NSQLComplete {
}
if constexpr (std::is_base_of_v<TTypeName, T>) {
+ switch (name.Kind) {
+ case TTypeName::EKind::Simple: {
+ } break;
+ case TTypeName::EKind::Container: {
+ name.Indentifier += "<";
+ } break;
+ case TTypeName::EKind::Parameterized: {
+ name.Indentifier += "(";
+ } break;
+ }
return {ECandidateKind::TypeName, std::move(name.Indentifier)};
}
@@ -221,6 +240,10 @@ namespace NSQLComplete {
return {ECandidateKind::ClusterName, std::move(name.Indentifier)};
}
+ if constexpr (std::is_base_of_v<TColumnName, T>) {
+ return {ECandidateKind::ColumnName, std::move(name.Indentifier)};
+ }
+
if constexpr (std::is_base_of_v<TBindingName, T>) {
if (!context.Binding) {
name.Indentifier.prepend('$');
@@ -253,17 +276,17 @@ namespace NSQLComplete {
}
ISqlCompletionEngine::TConfiguration MakeYDBConfiguration() {
- return {
- .IgnoredRules = {
- "use_stmt",
- "import_stmt",
- "export_stmt",
- },
+ ISqlCompletionEngine::TConfiguration config;
+ config.IgnoredRules = {
+ "use_stmt",
+ "import_stmt",
+ "export_stmt",
};
+ return config;
}
ISqlCompletionEngine::TConfiguration MakeYQLConfiguration() {
- return MakeConfiguration(/* allowedStmts = */ {
+ auto config = MakeConfiguration(/* allowedStmts = */ {
"lambda_stmt",
"pragma_stmt",
"select_stmt",
@@ -281,6 +304,18 @@ namespace NSQLComplete {
"for_stmt",
"values_stmt",
});
+
+ config.DisabledPreviousByToken = {};
+
+ config.ForcedPreviousByToken = {
+ {"PARALLEL", {}},
+ {"TABLESTORE", {}},
+ {"FOR", {"EVALUATE"}},
+ {"IF", {"EVALUATE"}},
+ {"EXTERNAL", {"USING"}},
+ };
+
+ return config;
}
ISqlCompletionEngine::TPtr MakeSqlCompletionEngine(
@@ -323,6 +358,9 @@ void Out<NSQLComplete::ECandidateKind>(IOutputStream& out, NSQLComplete::ECandid
case NSQLComplete::ECandidateKind::BindingName:
out << "BindingName";
break;
+ case NSQLComplete::ECandidateKind::ColumnName:
+ out << "ColumnName";
+ break;
case NSQLComplete::ECandidateKind::UnknownName:
out << "UnknownName";
break;
diff --git a/yql/essentials/sql/v1/complete/sql_complete.h b/yql/essentials/sql/v1/complete/sql_complete.h
index df5159aff3c..90edceacbc4 100644
--- a/yql/essentials/sql/v1/complete/sql_complete.h
+++ b/yql/essentials/sql/v1/complete/sql_complete.h
@@ -9,13 +9,14 @@
#include <util/generic/string.h>
#include <util/generic/vector.h>
+#include <util/generic/hash.h>
#include <util/generic/hash_set.h>
namespace NSQLComplete {
struct TCompletedToken {
TStringBuf Content;
- size_t SourcePosition;
+ size_t SourcePosition = 0;
};
enum class ECandidateKind {
@@ -27,6 +28,7 @@ namespace NSQLComplete {
FolderName,
TableName,
ClusterName,
+ ColumnName,
BindingName,
UnknownName,
};
@@ -44,18 +46,31 @@ namespace NSQLComplete {
TVector<TCandidate> Candidates;
};
+ // TODO(YQL-19747): Make it thread-safe.
class ISqlCompletionEngine {
public:
using TPtr = THolder<ISqlCompletionEngine>;
struct TConfiguration {
+ friend class TSqlCompletionEngine;
+ friend ISqlCompletionEngine::TConfiguration MakeYDBConfiguration();
+ friend ISqlCompletionEngine::TConfiguration MakeYQLConfiguration();
+ friend ISqlCompletionEngine::TConfiguration MakeConfiguration(THashSet<TString> allowedStmts);
+
+ public:
size_t Limit = 256;
+
+ private:
THashSet<TString> IgnoredRules;
+ THashMap<TString, THashSet<TString>> DisabledPreviousByToken;
+ THashMap<TString, THashSet<TString>> ForcedPreviousByToken;
};
virtual ~ISqlCompletionEngine() = default;
+
virtual TCompletion
Complete(TCompletionInput input, TEnvironment env = {}) = 0;
+
virtual NThreading::TFuture<TCompletion> // TODO(YQL-19747): Migrate YDB CLI to `Complete` method
CompleteAsync(TCompletionInput input, TEnvironment env = {}) = 0;
};
diff --git a/yql/essentials/sql/v1/complete/sql_complete_ut.cpp b/yql/essentials/sql/v1/complete/sql_complete_ut.cpp
index 4ecc12e526f..1f29751d017 100644
--- a/yql/essentials/sql/v1/complete/sql_complete_ut.cpp
+++ b/yql/essentials/sql/v1/complete/sql_complete_ut.cpp
@@ -43,6 +43,7 @@ public:
Y_UNIT_TEST_SUITE(SqlCompleteTests) {
using ECandidateKind::BindingName;
using ECandidateKind::ClusterName;
+ using ECandidateKind::ColumnName;
using ECandidateKind::FolderName;
using ECandidateKind::FunctionName;
using ECandidateKind::HintName;
@@ -83,7 +84,7 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) {
},
};
- THashMap<TString, THashMap<TString, TVector<TFolderEntry>>> fs = {
+ THashMap<TString, THashMap<TString, TVector<TFolderEntry>>> folders = {
{"", {{"/", {{"Folder", "local"},
{"Folder", "test"},
{"Folder", "prod"},
@@ -103,15 +104,18 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) {
{{"/", {{"Table", "maxim"}}}}},
};
+ THashMap<TString, THashMap<TString, TTableDetails>> tables = {
+ {"example", {{"/people", {{"name", "age"}}}}}};
+
auto clustersIt = NFuncTools::Filter(
- [](const auto& x) { return !x.empty(); }, IterateKeys(fs));
+ [](const auto& x) { return !x.empty(); }, IterateKeys(folders));
TVector<TString> clusters(begin(clustersIt), end(clustersIt));
TFrequencyData frequency;
TVector<INameService::TPtr> children = {
MakeStaticNameService(std::move(names), frequency),
- MakeSchemaNameService(MakeSimpleSchema(MakeStaticSimpleSchema(std::move(fs)))),
+ MakeSchemaNameService(MakeSimpleSchema(MakeStaticSimpleSchema(std::move(folders), std::move(tables)))),
MakeClusterNameService(MakeStaticClusterDiscovery(std::move(clusters))),
};
INameService::TPtr service = MakeUnionNameService(
@@ -475,37 +479,40 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) {
TVector<TCandidate> expected = {
{Keyword, "ALL"},
{Keyword, "BITCAST("},
- {Keyword, "CALLABLE"},
{Keyword, "CASE"},
{Keyword, "CAST("},
{Keyword, "CURRENT_DATE"},
{Keyword, "CURRENT_TIME"},
{Keyword, "CURRENT_TIMESTAMP"},
- {Keyword, "Dict<"},
+ {TypeName, "Callable<"},
{Keyword, "DISTINCT"},
{FunctionName, "DateTime::Split("},
+ {TypeName, "Decimal("},
+ {TypeName, "Dict<"},
{Keyword, "EMPTY_ACTION"},
- {Keyword, "ENUM"},
{Keyword, "EXISTS("},
+ {TypeName, "Enum<"},
{Keyword, "FALSE"},
- {Keyword, "Flow<"},
+ {TypeName, "Flow<"},
{Keyword, "JSON_EXISTS("},
{Keyword, "JSON_QUERY("},
{Keyword, "JSON_VALUE("},
- {Keyword, "List<"},
+ {TypeName, "List<"},
{Keyword, "NOT"},
{Keyword, "NULL"},
- {Keyword, "Optional<"},
+ {TypeName, "Optional<"},
{FunctionName, "Python::__private("},
- {Keyword, "Resource<"},
- {Keyword, "Set<"},
+ {TypeName, "Resource<"},
{Keyword, "STREAM"},
- {Keyword, "STRUCT"},
+ {TypeName, "Set<"},
{FunctionName, "StartsWith("},
- {Keyword, "Tagged<"},
+ {TypeName, "Stream<"},
+ {TypeName, "Struct<"},
{Keyword, "TRUE"},
- {Keyword, "TUPLE"},
- {Keyword, "VARIANT"},
+ {TypeName, "Tagged<"},
+ {TypeName, "Tuple<"},
+ {TypeName, "Uint64"},
+ {TypeName, "Variant<"},
};
auto engine = MakeSqlCompletionEngineUT();
@@ -689,8 +696,8 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) {
{Keyword, "ANY"},
};
UNIT_ASSERT_VALUES_EQUAL(Complete(engine, R"(
- USE example;
- DEFINE ACTION $hello() AS
+ USE example;
+ DEFINE ACTION $hello() AS
USE yt:saurus;
SELECT * FROM #;
END DEFINE;
@@ -721,36 +728,38 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) {
Y_UNIT_TEST(SelectWhere) {
TVector<TCandidate> expected = {
{Keyword, "BITCAST("},
- {Keyword, "CALLABLE"},
{Keyword, "CASE"},
{Keyword, "CAST("},
{Keyword, "CURRENT_DATE"},
{Keyword, "CURRENT_TIME"},
{Keyword, "CURRENT_TIMESTAMP"},
- {Keyword, "Dict<"},
+ {TypeName, "Callable<"},
{FunctionName, "DateTime::Split("},
+ {TypeName, "Decimal("},
+ {TypeName, "Dict<"},
{Keyword, "EMPTY_ACTION"},
- {Keyword, "ENUM"},
{Keyword, "EXISTS("},
+ {TypeName, "Enum<"},
{Keyword, "FALSE"},
- {Keyword, "Flow<"},
+ {TypeName, "Flow<"},
{Keyword, "JSON_EXISTS("},
{Keyword, "JSON_QUERY("},
{Keyword, "JSON_VALUE("},
- {Keyword, "List<"},
+ {TypeName, "List<"},
{Keyword, "NOT"},
{Keyword, "NULL"},
- {Keyword, "Optional<"},
+ {TypeName, "Optional<"},
{FunctionName, "Python::__private("},
- {Keyword, "Resource<"},
- {Keyword, "Set<"},
- {Keyword, "Stream<"},
- {Keyword, "STRUCT"},
+ {TypeName, "Resource<"},
+ {TypeName, "Set<"},
{FunctionName, "StartsWith("},
- {Keyword, "Tagged<"},
+ {TypeName, "Stream<"},
+ {TypeName, "Struct<"},
{Keyword, "TRUE"},
- {Keyword, "TUPLE"},
- {Keyword, "VARIANT"},
+ {TypeName, "Tagged<"},
+ {TypeName, "Tuple<"},
+ {TypeName, "Uint64"},
+ {TypeName, "Variant<"},
};
auto engine = MakeSqlCompletionEngineUT();
@@ -791,21 +800,21 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) {
Y_UNIT_TEST(TypeName) {
TVector<TCandidate> expected = {
- {Keyword, "Callable<("},
- {Keyword, "Decimal("},
- {Keyword, "Dict<"},
- {Keyword, "Enum<"},
- {Keyword, "Flow<"},
- {Keyword, "List<"},
- {Keyword, "Optional<"},
- {Keyword, "Resource<"},
- {Keyword, "Set<"},
- {Keyword, "Stream<"},
- {Keyword, "STRUCT"},
- {Keyword, "Tagged<"},
- {Keyword, "TUPLE"},
+ {TypeName, "Callable<"},
+ {TypeName, "Decimal("},
+ {TypeName, "Dict<"},
+ {TypeName, "Enum<"},
+ {TypeName, "Flow<"},
+ {TypeName, "List<"},
+ {TypeName, "Optional<"},
+ {TypeName, "Resource<"},
+ {TypeName, "Set<"},
+ {TypeName, "Stream<"},
+ {TypeName, "Struct<"},
+ {TypeName, "Tagged<"},
+ {TypeName, "Tuple<"},
{TypeName, "Uint64"},
- {Keyword, "Variant<"},
+ {TypeName, "Variant<"},
};
auto engine = MakeSqlCompletionEngineUT();
@@ -825,7 +834,7 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) {
}
{
TVector<TCandidate> expected = {
- {Keyword, "Optional<"},
+ {TypeName, "Optional<"},
};
UNIT_ASSERT_VALUES_EQUAL(Complete(engine, "SELECT Nothing(Option"), expected);
}
@@ -995,7 +1004,7 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) {
$=0;
$a=0;
$abac=0;
- SELECT
+ SELECT
)";
{
@@ -1040,6 +1049,31 @@ Y_UNIT_TEST_SUITE(SqlCompleteTests) {
CompleteTop(1, engine, "SELECT Max(#)").at(0).Kind, FolderName);
}
+ Y_UNIT_TEST(ColumnsAtSimpleSelect) {
+ auto engine = MakeSqlCompletionEngineUT();
+ {
+ TVector<TCandidate> expected = {
+ {ColumnName, "age"},
+ {ColumnName, "name"},
+ };
+ UNIT_ASSERT_VALUES_EQUAL(CompleteTop(2, engine, "SELECT # FROM example.`/people`"), expected);
+ }
+ {
+ TVector<TCandidate> expected = {
+ {ColumnName, "age"},
+ {Keyword, "ALL"},
+ };
+ UNIT_ASSERT_VALUES_EQUAL(CompleteTop(2, engine, "SELECT a# FROM example.`/people`"), expected);
+ }
+ {
+ TVector<TCandidate> expected = {
+ {ColumnName, "age"},
+ {ColumnName, "name"},
+ };
+ UNIT_ASSERT_VALUES_EQUAL(CompleteTop(2, engine, "USE example; SELECT # FROM `/people`"), expected);
+ }
+ }
+
Y_UNIT_TEST(Typing) {
const auto queryUtf16 = TUtf16String::FromUtf8(
"SELECT \n"
@@ -1065,7 +1099,7 @@ SELECT
123467, \"Hello, {name}! 编码\"},
(1 + (5 * 1 / 0)), MIN(identifier),
Bool(field), Math::Sin(var)
-FROM `local/test/space/table`
+FROM `local/test/space/table`
JOIN yt:$cluster_name.test;
)";
@@ -1285,6 +1319,24 @@ JOIN yt:$cluster_name.test;
UNIT_ASSERT_UNEQUAL(Complete(engine, {"SELE"}).size(), 0);
}
+ Y_UNIT_TEST(IgnoredTokens) {
+ auto lexer = MakePureLexerSupplier();
+
+ TNameSet names;
+ TFrequencyData frequency;
+ auto service = MakeStaticNameService(names, MakeDefaultRanking(frequency));
+
+ auto config = MakeYQLConfiguration();
+ auto engine = MakeSqlCompletionEngine(lexer, std::move(service), config);
+
+ UNIT_ASSERT(!FindPtr(Complete(engine, {""}), TCandidate{Keyword, "FOR"}));
+ UNIT_ASSERT(!FindPtr(Complete(engine, {""}), TCandidate{Keyword, "PARALLEL"}));
+
+ UNIT_ASSERT(FindPtr(Complete(engine, {"EVALUATE "}), TCandidate{Keyword, "FOR"}));
+ UNIT_ASSERT(FindPtr(Complete(engine, {"EVALUATE "}), TCandidate{Keyword, "FOR"}));
+ UNIT_ASSERT(FindPtr(Complete(engine, {"EVALUATE /**/"}), TCandidate{Keyword, "FOR"}));
+ }
+
Y_UNIT_TEST(CachedSchema) {
TLexerSupplier lexer = MakePureLexerSupplier();
diff --git a/yql/essentials/sql/v1/complete/syntax/format.cpp b/yql/essentials/sql/v1/complete/syntax/format.cpp
index 855c152bed4..3037faced5c 100644
--- a/yql/essentials/sql/v1/complete/syntax/format.cpp
+++ b/yql/essentials/sql/v1/complete/syntax/format.cpp
@@ -22,23 +22,6 @@ namespace NSQLComplete {
return keywords;
}();
- const THashSet<TString> TypeConstructors = {
- "DECIMAL",
- "OPTIONAL",
- "TUPLE",
- "STRUCT",
- "VARIANT",
- "LIST",
- "STREAM",
- "FLOW",
- "DICT",
- "SET",
- "ENUM",
- "RESOURCE",
- "TAGGED",
- "CALLABLE",
- };
-
} // namespace
TString FormatKeywords(const TVector<TString>& seq) {
@@ -46,25 +29,14 @@ namespace NSQLComplete {
return "";
}
- size_t i = 0;
- TString text = seq[i++];
-
- if (2 <= seq.size() &&
- TypeConstructors.contains(text) &&
- (seq[i] == "<" || seq[i] == "(")) {
- text.to_title();
- text.append(seq[i]);
- i += 1;
- }
-
- for (; i < seq.size(); ++i) {
+ TString text = seq[0];
+ for (size_t i = 1; i < seq.size(); ++i) {
const auto& token = seq[i];
if (Keywords.contains(token)) {
text += " ";
}
text += token;
}
-
return text;
}
diff --git a/yql/essentials/sql/v1/complete/syntax/grammar.cpp b/yql/essentials/sql/v1/complete/syntax/grammar.cpp
index 790f272db86..3c0dd579e4f 100644
--- a/yql/essentials/sql/v1/complete/syntax/grammar.cpp
+++ b/yql/essentials/sql/v1/complete/syntax/grammar.cpp
@@ -34,6 +34,12 @@ namespace NSQLComplete {
return Parser_->getRuleNames().at(rule);
}
+ TTokenId GetTokenId(std::string_view symbolized) const override {
+ TTokenId type = Parser_->getTokenType(symbolized);
+ Y_ENSURE(type != antlr4::Token::INVALID_TYPE, "Not found " << symbolized);
+ return type;
+ }
+
TRuleId GetRuleId(std::string_view symbolized) const override {
TRuleId index = Parser_->getRuleIndex(std::string(symbolized));
if (index == INVALID_INDEX) {
diff --git a/yql/essentials/sql/v1/complete/syntax/grammar.h b/yql/essentials/sql/v1/complete/syntax/grammar.h
index 29b81a78984..7e6bb398439 100644
--- a/yql/essentials/sql/v1/complete/syntax/grammar.h
+++ b/yql/essentials/sql/v1/complete/syntax/grammar.h
@@ -22,6 +22,7 @@ namespace NSQLComplete {
virtual ~ISqlGrammar() = default;
virtual const antlr4::dfa::Vocabulary& GetVocabulary() const = 0;
virtual const std::string& SymbolizedRule(TRuleId rule) const = 0;
+ virtual TTokenId GetTokenId(std::string_view symbolized) const = 0;
virtual TRuleId GetRuleId(std::string_view symbolized) const = 0;
virtual const std::vector<std::string>& GetAllRules() const = 0;
virtual const std::unordered_set<TTokenId>& GetAllTokens() const = 0;
diff --git a/yql/essentials/sql/v1/complete/syntax/ya.make b/yql/essentials/sql/v1/complete/syntax/ya.make
index 6a35a80375e..f60a05f7b59 100644
--- a/yql/essentials/sql/v1/complete/syntax/ya.make
+++ b/yql/essentials/sql/v1/complete/syntax/ya.make
@@ -14,6 +14,7 @@ PEERDIR(
yql/essentials/sql/settings
yql/essentials/sql/v1/lexer
yql/essentials/sql/v1/reflect
+ yql/essentials/sql/v1/complete/antlr4
yql/essentials/sql/v1/complete/core
yql/essentials/sql/v1/complete/text
)
diff --git a/yql/essentials/tests/common/test_framework/yql_utils.py b/yql/essentials/tests/common/test_framework/yql_utils.py
index 685a6ab7278..81a7fa47bae 100644
--- a/yql/essentials/tests/common/test_framework/yql_utils.py
+++ b/yql/essentials/tests/common/test_framework/yql_utils.py
@@ -57,7 +57,7 @@ def do_custom_error_check(res, sql_query):
err_string = custom_error.group(1).strip()
assert err_string, 'Expected custom error check in test.\nTest error: %s' % res.std_err
log('Custom error: ' + err_string)
- assert err_string in res.std_err, '"' + err_string + '" is not found'
+ assert err_string in res.std_err, '"' + err_string + '" is not found in "' + res.std_err + "'"
def get_gateway_cfg_suffix():
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructExtraItemsFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructExtraItemsFail.yqls
index 5fac5c72de8..31944700c1e 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructExtraItemsFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructExtraItemsFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error: Failed to convert type: Variant<'A':Int32,'B':Int32,'C':Int32,'D':Int32> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<-D:Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructNameMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructNameMismatchFail.yqls
index 213e112427d..402063a8387 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructNameMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructNameMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<'A':Int32,'B':Int32,'X':Int32> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<-X:Int32,+C:Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTargetNameMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTargetNameMismatchFail.yqls
index c84a22312a6..3747824d740 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTargetNameMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTargetNameMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<'A':Int32,'C':Int32,'X':Int32> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<-X:Int32,+B:Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTargetTypeMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTargetTypeMismatchFail.yqls
index cc374209082..b468cd2f4ee 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTargetTypeMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTargetTypeMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error: Failed to convert type: Variant<'A':Int32,'B':Float,'C':Int32> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<B:Float!=Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTypeMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTypeMismatchFail.yqls
index 4a3e6a91d3b..8a89730c778 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTypeMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverStructTypeMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<'A':Int32,'B':Int32,'C':Float> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<C:Float!=Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleExtraItemsFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleExtraItemsFail.yqls
index e36ad06513a..bcf1aba80e4 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleExtraItemsFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleExtraItemsFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error: Failed to convert type: Variant<Int32,Int32,Int32,Int32> to Variant<Int32,Int32,Int32>*/
+# /* custom error: type diff: Variant<-Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleNotEnoughItemsFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleNotEnoughItemsFail.yqls
index a44c8483bc2..f8979971dae 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleNotEnoughItemsFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleNotEnoughItemsFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error: Failed to convert type: Variant<Int32,Int32,Int32> to Variant<Int32,Int32,Int32,Int32>*/
+# /* custom error: type diff: Variant<+Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleTargetTypeMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleTargetTypeMismatchFail.yqls
index 82b30b4d4bf..e5fb6288e41 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleTargetTypeMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleTargetTypeMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<Int32,Float,Int32> to Variant<Int32,Int32,Int32>*/
+# /* custom error: type diff: Variant<1:Float!=Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleTypeMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleTypeMismatchFail.yqls
index f69cfaaab33..282cb998893 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleTypeMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralOverTupleTypeMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error: Failed to convert type: Variant<Int32,Int32,Float> to Variant<Int32,Int32,Int32>*/
+# /* custom error: type diff: Variant<2:Float!=Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralUnderlyingTypeMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralUnderlyingTypeMismatchFail.yqls
index 2a0ca17bf6f..962c25bffa9 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralUnderlyingTypeMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantLiteralUnderlyingTypeMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<Int32,Int32,Int32> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<Tuple!=Struct> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructExtraItemsFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructExtraItemsFail.yqls
index c081180cc73..7182cda623c 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructExtraItemsFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructExtraItemsFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<'A':Int32,'B':Int32,'C':Int32,'D':Int32> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<-D:Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructNameMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructNameMismatchFail.yqls
index 6dd91fa2146..1d2a97e4872 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructNameMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructNameMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<'A':Int32,'B':Int32,'X':Int32> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<-X:Int32,+C:Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTargetNameMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTargetNameMismatchFail.yqls
index 254361eaf77..5b7f16b62be 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTargetNameMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTargetNameMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<'A':Int32,'C':Int32,'X':Int32> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<-X:Int32,+B:Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTargetTypeMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTargetTypeMismatchFail.yqls
index 29df2cf7804..d25c3a1a732 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTargetTypeMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTargetTypeMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<'A':Int32,'B':Float,'C':Int32> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<B:Float!=Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTypeMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTypeMismatchFail.yqls
index c8b6d4d8559..6de4238813f 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTypeMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverStructTypeMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error: Failed to convert type: Variant<'A':Int32,'B':Int32,'C':Float> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<C:Float!=Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleNotEnoughItemsFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleNotEnoughItemsFail.yqls
index dfbefedea26..4ee670f0dc0 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleNotEnoughItemsFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleNotEnoughItemsFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<Int32,Int32,Int32> to Variant<Int32,Int32,Int32,Int32>*/
+# /* custom error: type diff: Variant<+Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleTargetTypeMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleTargetTypeMismatchFail.yqls
index 072e25c9729..ffb47e2676e 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleTargetTypeMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleTargetTypeMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<Int32,Float,Int32> to Variant<Int32,Int32,Int32>*/
+# /* custom error: type diff: Variant<1:Float!=Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleTypeMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleTypeMismatchFail.yqls
index 9818059f1b2..cb32b8ca7b6 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleTypeMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantOverTupleTypeMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<Int32,Int32,Float> to Variant<Int32,Int32,Int32>*/
+# /* custom error: type diff: Variant<2:Float!=Int32> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantUnderlyingTypeMismatchFail.yqls b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantUnderlyingTypeMismatchFail.yqls
index c2834203dca..bf7a6c76194 100644
--- a/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantUnderlyingTypeMismatchFail.yqls
+++ b/yql/essentials/tests/s-expressions/suites/ImplictCasts/VariantUnderlyingTypeMismatchFail.yqls
@@ -1,4 +1,4 @@
-# /* custom error:Failed to convert type: Variant<Int32,Int32,Int32> to Variant<'A':Int32,'B':Int32,'C':Int32>*/
+# /* custom error: type diff: Variant<Tuple!=Struct> */
(
(let config (DataSource 'config))
(let res_sink (DataSink 'result))
diff --git a/yql/essentials/tests/sql/minirun/part0/canondata/test.test_expr-dict_common_type--Results_/extracted b/yql/essentials/tests/sql/minirun/part0/canondata/test.test_expr-dict_common_type--Results_/extracted
index 1dd6413dbea..a1843926b5c 100644
--- a/yql/essentials/tests/sql/minirun/part0/canondata/test.test_expr-dict_common_type--Results_/extracted
+++ b/yql/essentials/tests/sql/minirun/part0/canondata/test.test_expr-dict_common_type--Results_/extracted
@@ -6,7 +6,7 @@
<tmp_path>/program.sql:<main>:14:8: Warning: At function: AsList
select AsList({100u:100}, $d1, $d2, $d3, $d4);
^
- <tmp_path>/program.sql:<main>:6:7: Warning: Failed to convert type: Dict<Int32,Uint32> to Dict<Int32,Int32>
+ <tmp_path>/program.sql:<main>:6:7: Warning: Failed to convert, type diff: Dict<payload:Uint32!=Int32>
$d1 = ToDict([(1, 1u)]);
^
<tmp_path>/program.sql:<main>:6:7: Warning: Consider using explicit CAST or BITCAST to convert from Uint32 to Int32
@@ -18,13 +18,13 @@
<tmp_path>/program.sql:<main>:15:8: Warning: At function: AsList
select AsList({100}, $s1, $s2);
^
- <tmp_path>/program.sql:/lib/yql/core.yqls:xxx:yyy: Warning: Failed to convert type: Set<Uint32> to Set<Int32>
+ <tmp_path>/program.sql:/lib/yql/core.yqls:xxx:yyy: Warning: Failed to convert, type diff: Dict<key:Uint32!=Int32>
^
<tmp_path>/program.sql:/lib/yql/core.yqls:xxx:yyy: Warning: Consider using explicit CAST or BITCAST to convert from Uint32 to Int32
^
- <tmp_path>/program.sql:<main>:12:7: Warning: Failed to convert type: Set<Uint32> to Set<Int32>
+ <tmp_path>/program.sql:<main>:12:7: Warning: Failed to convert, type diff: Dict<key:Uint32!=Int32>
$s2 = AsSet(2u);
^
<tmp_path>/program.sql:<main>:12:7: Warning: Consider using explicit CAST or BITCAST to convert from Uint32 to Int32
diff --git a/yql/essentials/tools/yql_complete/yql_complete.cpp b/yql/essentials/tools/yql_complete/yql_complete.cpp
index 7d9eaded2e6..2a940c4247e 100644
--- a/yql/essentials/tools/yql_complete/yql_complete.cpp
+++ b/yql/essentials/tools/yql_complete/yql_complete.cpp
@@ -76,28 +76,19 @@ int Run(int argc, char* argv[]) {
auto engine = NSQLComplete::MakeSqlCompletionEngine(
MakePureLexerSupplier(),
NSQLComplete::MakeStaticNameService(
- NSQLComplete::LoadDefaultNameSet(),
+ NSQLComplete::LoadDefaultNameSet(),
std::move(frequency)));
- NSQLComplete::TCompletionInput input;
-
- input.Text = queryString;
- if (!NYql::IsUtf8(input.Text)) {
+ if (!NYql::IsUtf8(queryString)) {
ythrow yexception() << "provided input is not UTF encoded";
}
- if (pos) {
- input.CursorPosition = UTF8PositionToBytes(input.Text, *pos);
- } else if (Count(input.Text, '#') == 1) {
- Cerr << "Note: found an only '#', setting the cursor position\n";
- input.CursorPosition = input.Text.find('#');
- } else if (Count(input.Text, '#') >= 2) {
- Cerr << "Note: found multiple '#', defaulting the cursor position\n";
- input.CursorPosition = queryString.size();
- } else {
- input.CursorPosition = queryString.size();
+ if (auto count = Count(queryString, '#'); 1 < count) {
+ ythrow yexception() << "provided input contains " << count << " '#', expected 0 or 1";
}
+ NSQLComplete::TCompletionInput input = NSQLComplete::SharpedInput(queryString);
+
auto output = engine->CompleteAsync(input).ExtractValueSync();
for (const auto& c : output.Candidates) {
Cout << "[" << c.Kind << "] " << c.Content << "\n";
diff --git a/yql/essentials/udfs/common/string/string_udf.cpp b/yql/essentials/udfs/common/string/string_udf.cpp
index 5c24485129d..f42fcfd2479 100644
--- a/yql/essentials/udfs/common/string/string_udf.cpp
+++ b/yql/essentials/udfs/common/string/string_udf.cpp
@@ -185,7 +185,7 @@ SIMPLE_STRICT_UDF_OPTIONS(TReverse, TOptional<char*>(TOptional<char*>),
} \
}
-#define STRING_ASCII_CMP_IGNORE_CASE_UDF(udfName, function) \
+#define STRING_ASCII_CMP_IGNORE_CASE_UDF(udfName, function, minVersion) \
TUnboxedValuePod udfName##Impl(const TUnboxedValuePod* args) { \
if (args[0]) { \
const TString haystack(args[0].AsStringRef()); \
@@ -215,7 +215,7 @@ SIMPLE_STRICT_UDF_OPTIONS(TReverse, TOptional<char*>(TOptional<char*>),
\
BEGIN_SIMPLE_STRICT_ARROW_UDF_OPTIONS(T##udfName, \
bool(TOptional<char*>, char*), \
- builder.SetMinLangVer(NYql::MakeLangVersion(2025, 2))) \
+ builder.SetMinLangVer(minVersion)) \
{ \
Y_UNUSED(valueBuilder); \
return udfName##Impl(args); \
@@ -439,10 +439,10 @@ SIMPLE_STRICT_UDF_OPTIONS(TReverse, TOptional<char*>(TOptional<char*>),
XX(HasPrefixIgnoreCase, AsciiHasPrefixIgnoreCase) \
XX(HasSuffixIgnoreCase, AsciiHasSuffixIgnoreCase)
-#define STRING_ASCII_CMP_IGNORE_CASE_UDF_MAP(XX) \
- XX(AsciiStartsWithIgnoreCase, AsciiHasPrefixIgnoreCase) \
- XX(AsciiEndsWithIgnoreCase, AsciiHasSuffixIgnoreCase) \
- XX(AsciiEqualsIgnoreCase, AsciiEqualsIgnoreCase)
+#define STRING_ASCII_CMP_IGNORE_CASE_UDF_MAP(XX) \
+ XX(AsciiStartsWithIgnoreCase, AsciiHasPrefixIgnoreCase, NYql::MakeLangVersion(2025, 1)) \
+ XX(AsciiEndsWithIgnoreCase, AsciiHasSuffixIgnoreCase, NYql::MakeLangVersion(2025, 1)) \
+ XX(AsciiEqualsIgnoreCase, AsciiEqualsIgnoreCase, NYql::MakeLangVersion(2025, 2))
// NOTE: The functions below are marked as deprecated, so block implementation
// is not required for them. Hence, STROKA_UDF provides only the scalar one at
diff --git a/yql/essentials/udfs/common/string/test/canondata/result.json b/yql/essentials/udfs/common/string/test/canondata/result.json
index 0feffac589c..a99f95f7db6 100644
--- a/yql/essentials/udfs/common/string/test/canondata/result.json
+++ b/yql/essentials/udfs/common/string/test/canondata/result.json
@@ -14,6 +14,11 @@
"uri": "file://test.test_AsciiCmpIgnoreCase_2025_02_/extracted"
}
],
+ "test.test[AsciiCmpIgnoreCase_AllAlternatives_2025_01]": [
+ {
+ "uri": "file://test.test_AsciiCmpIgnoreCase_AllAlternatives_2025_01_/results.txt"
+ }
+ ],
"test.test[AsciiContainsIgnoreCase_2025_01]": [
{
"uri": "file://test.test_AsciiContainsIgnoreCase_2025_01_/extracted"
diff --git a/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiCmpIgnoreCase_AllAlternatives_2025_01_/results.txt b/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiCmpIgnoreCase_AllAlternatives_2025_01_/results.txt
new file mode 100644
index 00000000000..b467eae86b1
--- /dev/null
+++ b/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiCmpIgnoreCase_AllAlternatives_2025_01_/results.txt
@@ -0,0 +1,121 @@
+[
+ {
+ "Write" = [
+ {
+ "Type" = [
+ "ListType";
+ [
+ "StructType";
+ [
+ [
+ "value";
+ [
+ "DataType";
+ "String"
+ ]
+ ];
+ [
+ "icprefix";
+ [
+ "DataType";
+ "Bool"
+ ]
+ ];
+ [
+ "icstarts";
+ [
+ "DataType";
+ "Bool"
+ ]
+ ];
+ [
+ "aicstarts";
+ [
+ "DataType";
+ "Bool"
+ ]
+ ];
+ [
+ "icsuffix";
+ [
+ "DataType";
+ "Bool"
+ ]
+ ];
+ [
+ "icends";
+ [
+ "DataType";
+ "Bool"
+ ]
+ ];
+ [
+ "aicends";
+ [
+ "DataType";
+ "Bool"
+ ]
+ ]
+ ]
+ ]
+ ];
+ "Data" = [
+ [
+ "fdsa";
+ %false;
+ %false;
+ %false;
+ %false;
+ %false;
+ %false
+ ];
+ [
+ "aswedfg";
+ %true;
+ %true;
+ %true;
+ %false;
+ %false;
+ %false
+ ];
+ [
+ "asdadsaasd";
+ %true;
+ %true;
+ %true;
+ %false;
+ %false;
+ %false
+ ];
+ [
+ "gdsfsassas";
+ %false;
+ %false;
+ %false;
+ %true;
+ %true;
+ %true
+ ];
+ [
+ "";
+ %false;
+ %false;
+ %false;
+ %false;
+ %false;
+ %false
+ ];
+ [
+ "`\xD0\x9F\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82, \xD0\xBC\xD0\xB8\xD1\x80!`";
+ %false;
+ %false;
+ %false;
+ %false;
+ %false;
+ %false
+ ]
+ ]
+ }
+ ]
+ }
+] \ No newline at end of file
diff --git a/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiContainsIgnoreCase_2025_01_/extracted b/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiContainsIgnoreCase_2025_01_/extracted
index 6c66d69cd7f..e663ef8331c 100644
--- a/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiContainsIgnoreCase_2025_01_/extracted
+++ b/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiContainsIgnoreCase_2025_01_/extracted
@@ -25,26 +25,8 @@
SELECT
^
<tmp_path>/program.sql:<main>:10:13: Error: At function: Apply, At function: Udf
- String::AsciiStartsWithIgnoreCase(value, "AS") AS icstarts,
- ^
- <tmp_path>/program.sql:<main>:10:13: Error: UDF 'String.AsciiStartsWithIgnoreCase' is not available before version 2025.02
- String::AsciiStartsWithIgnoreCase(value, "AS") AS icstarts,
- ^
- <tmp_path>/program.sql:<main>:2:1: Error: At function: SqlProjectItem, At lambda
- SELECT
- ^
- <tmp_path>/program.sql:<main>:12:13: Error: At function: Apply, At function: Udf
- String::AsciiEndsWithIgnoreCase(value, "AS") AS icends,
- ^
- <tmp_path>/program.sql:<main>:12:13: Error: UDF 'String.AsciiEndsWithIgnoreCase' is not available before version 2025.02
- String::AsciiEndsWithIgnoreCase(value, "AS") AS icends,
- ^
- <tmp_path>/program.sql:<main>:2:1: Error: At function: SqlProjectItem, At lambda
- SELECT
- ^
- <tmp_path>/program.sql:<main>:14:13: Error: At function: Apply, At function: Udf
String::AsciiEqualsIgnoreCase(value, "FDSA") AS icequals,
^
- <tmp_path>/program.sql:<main>:14:13: Error: UDF 'String.AsciiEqualsIgnoreCase' is not available before version 2025.02
+ <tmp_path>/program.sql:<main>:10:13: Error: UDF 'String.AsciiEqualsIgnoreCase' is not available before version 2025.02
String::AsciiEqualsIgnoreCase(value, "FDSA") AS icequals,
^ \ No newline at end of file
diff --git a/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiContainsIgnoreCase_2025_01_scan_/extracted b/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiContainsIgnoreCase_2025_01_scan_/extracted
index 6c66d69cd7f..e663ef8331c 100644
--- a/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiContainsIgnoreCase_2025_01_scan_/extracted
+++ b/yql/essentials/udfs/common/string/test/canondata/test.test_AsciiContainsIgnoreCase_2025_01_scan_/extracted
@@ -25,26 +25,8 @@
SELECT
^
<tmp_path>/program.sql:<main>:10:13: Error: At function: Apply, At function: Udf
- String::AsciiStartsWithIgnoreCase(value, "AS") AS icstarts,
- ^
- <tmp_path>/program.sql:<main>:10:13: Error: UDF 'String.AsciiStartsWithIgnoreCase' is not available before version 2025.02
- String::AsciiStartsWithIgnoreCase(value, "AS") AS icstarts,
- ^
- <tmp_path>/program.sql:<main>:2:1: Error: At function: SqlProjectItem, At lambda
- SELECT
- ^
- <tmp_path>/program.sql:<main>:12:13: Error: At function: Apply, At function: Udf
- String::AsciiEndsWithIgnoreCase(value, "AS") AS icends,
- ^
- <tmp_path>/program.sql:<main>:12:13: Error: UDF 'String.AsciiEndsWithIgnoreCase' is not available before version 2025.02
- String::AsciiEndsWithIgnoreCase(value, "AS") AS icends,
- ^
- <tmp_path>/program.sql:<main>:2:1: Error: At function: SqlProjectItem, At lambda
- SELECT
- ^
- <tmp_path>/program.sql:<main>:14:13: Error: At function: Apply, At function: Udf
String::AsciiEqualsIgnoreCase(value, "FDSA") AS icequals,
^
- <tmp_path>/program.sql:<main>:14:13: Error: UDF 'String.AsciiEqualsIgnoreCase' is not available before version 2025.02
+ <tmp_path>/program.sql:<main>:10:13: Error: UDF 'String.AsciiEqualsIgnoreCase' is not available before version 2025.02
String::AsciiEqualsIgnoreCase(value, "FDSA") AS icequals,
^ \ No newline at end of file
diff --git a/yql/essentials/udfs/common/string/test/cases/AsciiCmpIgnoreCase_AllAlternatives_2025_01.cfg b/yql/essentials/udfs/common/string/test/cases/AsciiCmpIgnoreCase_AllAlternatives_2025_01.cfg
new file mode 100644
index 00000000000..02e37255758
--- /dev/null
+++ b/yql/essentials/udfs/common/string/test/cases/AsciiCmpIgnoreCase_AllAlternatives_2025_01.cfg
@@ -0,0 +1,2 @@
+langver 2025.01
+in plato.Input default.in
diff --git a/yql/essentials/udfs/common/string/test/cases/AsciiCmpIgnoreCase_AllAlternatives_2025_01.sql b/yql/essentials/udfs/common/string/test/cases/AsciiCmpIgnoreCase_AllAlternatives_2025_01.sql
new file mode 100644
index 00000000000..854e414640b
--- /dev/null
+++ b/yql/essentials/udfs/common/string/test/cases/AsciiCmpIgnoreCase_AllAlternatives_2025_01.sql
@@ -0,0 +1,10 @@
+/* syntax version 1 */
+SELECT
+ value,
+ String::HasPrefixIgnoreCase(value, "AS") AS icprefix,
+ String::StartsWithIgnoreCase(value, "AS") AS icstarts,
+ String::AsciiStartsWithIgnoreCase(value, "AS") AS aicstarts,
+ String::HasSuffixIgnoreCase(value, "AS") AS icsuffix,
+ String::EndsWithIgnoreCase(value, "AS") AS icends,
+ String::AsciiEndsWithIgnoreCase(value, "AS") AS aicends,
+FROM Input;
diff --git a/yql/essentials/udfs/common/string/test/cases/AsciiContainsIgnoreCase_2025_01.sql b/yql/essentials/udfs/common/string/test/cases/AsciiContainsIgnoreCase_2025_01.sql
index db2ebad20e0..f41abd94ec4 100644
--- a/yql/essentials/udfs/common/string/test/cases/AsciiContainsIgnoreCase_2025_01.sql
+++ b/yql/essentials/udfs/common/string/test/cases/AsciiContainsIgnoreCase_2025_01.sql
@@ -2,8 +2,6 @@ SELECT
value,
String::AsciiContainsIgnoreCase(value, "AS") AS iccontains,
String::AsciiContainsIgnoreCase(value, "") AS icempty,
- String::AsciiStartsWithIgnoreCase(value, "AS") AS icstarts,
- String::AsciiEndsWithIgnoreCase(value, "AS") AS icends,
String::AsciiEqualsIgnoreCase(value, "FDSA") AS icequals,
FROM Input;
diff --git a/yql/essentials/udfs/common/string/test/cases/AsciiContainsIgnoreCase_2025_01_scan.sql b/yql/essentials/udfs/common/string/test/cases/AsciiContainsIgnoreCase_2025_01_scan.sql
index db2ebad20e0..f41abd94ec4 100644
--- a/yql/essentials/udfs/common/string/test/cases/AsciiContainsIgnoreCase_2025_01_scan.sql
+++ b/yql/essentials/udfs/common/string/test/cases/AsciiContainsIgnoreCase_2025_01_scan.sql
@@ -2,8 +2,6 @@ SELECT
value,
String::AsciiContainsIgnoreCase(value, "AS") AS iccontains,
String::AsciiContainsIgnoreCase(value, "") AS icempty,
- String::AsciiStartsWithIgnoreCase(value, "AS") AS icstarts,
- String::AsciiEndsWithIgnoreCase(value, "AS") AS icends,
String::AsciiEqualsIgnoreCase(value, "FDSA") AS icequals,
FROM Input;
diff --git a/yql/essentials/utils/backtrace/backtrace_lib.cpp b/yql/essentials/utils/backtrace/backtrace_lib.cpp
index c0c7b2c667a..dd2d295dc30 100644
--- a/yql/essentials/utils/backtrace/backtrace_lib.cpp
+++ b/yql/essentials/utils/backtrace/backtrace_lib.cpp
@@ -33,7 +33,7 @@ namespace {
return 0;
}
#endif
- bool comp(const TDllInfo& a, const TDllInfo& b) {
+ bool Comp(const TDllInfo& a, const TDllInfo& b) {
return strcmp(a.Path, b.Path) < 0;
}
@@ -49,7 +49,7 @@ namespace NYql {
memset(&dlInfo, 0, sizeof(dlInfo));
auto ret = dladdr(reinterpret_cast<void*>(addr), &dlInfo);
if (ret) {
- auto it = std::lower_bound(DLLs, DLLs + DLLCount, std::remove_reference_t<decltype(DLLs[0])> {dlInfo.dli_fname, {}}, comp);
+ auto it = std::lower_bound(DLLs, DLLs + DLLCount, std::remove_reference_t<decltype(DLLs[0])> {dlInfo.dli_fname, {}}, Comp);
if (it != DLLs + DLLCount && !strcmp(it->Path, dlInfo.dli_fname)) {
File = it->Path;
Address -= it->BaseAddress;
@@ -63,7 +63,7 @@ namespace NYql {
DLLCount = 0;
dl_iterate_phdr(DlIterCallback, &DLLs);
#endif
- std::stable_sort(DLLs, DLLs + DLLCount, comp);
+ std::stable_sort(DLLs, DLLs + DLLCount, Comp);
size_t cnt = CollectBacktrace(Stack, Limit, data);
return CollectFrames(frames, Stack, cnt);
}
@@ -75,4 +75,5 @@ namespace NYql {
return cnt;
}
}
-} \ No newline at end of file
+}
+
diff --git a/yql/essentials/utils/failure_injector/failure_injector.cpp b/yql/essentials/utils/failure_injector/failure_injector.cpp
index 4f4f9c1eb69..dfaff74503a 100644
--- a/yql/essentials/utils/failure_injector/failure_injector.cpp
+++ b/yql/essentials/utils/failure_injector/failure_injector.cpp
@@ -30,8 +30,8 @@ THashMap<TString, TFailureInjector::TFailureSpec> TFailureInjector::GetCurrentSt
THashMap<TString, TFailureInjector::TFailureSpec> TFailureInjector::GetCurrentStateImpl() {
THashMap<TString, TFailureInjector::TFailureSpec> copy;
- with_lock(Lock) {
- copy = FailureSpecs;
+ with_lock(Lock_) {
+ copy = FailureSpecs_;
}
return copy;
}
@@ -40,8 +40,8 @@ void TFailureInjector::ReachImpl(std::string_view name, std::function<void()> ac
if (!Enabled_.load()) {
return;
}
- with_lock(Lock) {
- if (auto failureSpec = FailureSpecs.FindPtr(name)) {
+ with_lock(Lock_) {
+ if (auto failureSpec = FailureSpecs_.FindPtr(name)) {
YQL_LOG(DEBUG) << "TFailureInjector::Reach: " << name << ", Skip=" << failureSpec->Skip << ", Fails=" << failureSpec->CountOfFails;
if (failureSpec->Skip > 0) {
--failureSpec->Skip;
@@ -55,9 +55,9 @@ void TFailureInjector::ReachImpl(std::string_view name, std::function<void()> ac
}
void TFailureInjector::SetImpl(std::string_view name, ui64 skip, ui64 countOfFails) {
- with_lock(Lock) {
+ with_lock(Lock_) {
YQL_ENSURE(countOfFails > 0, "failure " << name << ", 'countOfFails' must be positive");
- FailureSpecs[TString{name}] = TFailureSpec{skip, countOfFails};
+ FailureSpecs_[TString{name}] = TFailureSpec{skip, countOfFails};
}
}
diff --git a/yql/essentials/utils/failure_injector/failure_injector.h b/yql/essentials/utils/failure_injector/failure_injector.h
index 6db79fc8c0e..227eb1518f1 100644
--- a/yql/essentials/utils/failure_injector/failure_injector.h
+++ b/yql/essentials/utils/failure_injector/failure_injector.h
@@ -29,8 +29,8 @@ private:
THashMap<TString, TFailureSpec> GetCurrentStateImpl();
std::atomic<bool> Enabled_ = false;
- THashMap<TString, TFailureSpec> FailureSpecs;
- TMutex Lock;
+ THashMap<TString, TFailureSpec> FailureSpecs_;
+ TMutex Lock_;
};
} // NYql
diff --git a/yql/essentials/utils/fetch/fetch.cpp b/yql/essentials/utils/fetch/fetch.cpp
index d35baeb0974..0797e81b2a7 100644
--- a/yql/essentials/utils/fetch/fetch.cpp
+++ b/yql/essentials/utils/fetch/fetch.cpp
@@ -64,33 +64,33 @@ public:
rqs << "\r\n";
}
- Socket.Reset(new TSocket(TNetworkAddress(host, port), timeout));
- SocketInput.Reset(new TSocketInput(*Socket));
- SocketOutput.Reset(new TSocketOutput(*Socket));
+ Socket_.Reset(new TSocket(TNetworkAddress(host, port), timeout));
+ SocketInput_.Reset(new TSocketInput(*Socket_));
+ SocketOutput_.Reset(new TSocketOutput(*Socket_));
- Socket->SetSocketTimeout(timeout.Seconds(), timeout.MilliSeconds() % 1000);
+ Socket_->SetSocketTimeout(timeout.Seconds(), timeout.MilliSeconds() % 1000);
if (https) {
- Ssl.Reset(new TOpenSslClientIO(SocketInput.Get(), SocketOutput.Get()));
+ Ssl_.Reset(new TOpenSslClientIO(SocketInput_.Get(), SocketOutput_.Get()));
}
{
- THttpOutput ho(Ssl ? (IOutputStream*)Ssl.Get() : (IOutputStream*)SocketOutput.Get());
+ THttpOutput ho(Ssl_ ? (IOutputStream*)Ssl_.Get() : (IOutputStream*)SocketOutput_.Get());
(ho << req).Finish();
}
- HttpInput.Reset(new THttpInput(Ssl ? (IInputStream*)Ssl.Get() : (IInputStream*)SocketInput.Get()));
+ HttpInput_.Reset(new THttpInput(Ssl_ ? (IInputStream*)Ssl_.Get() : (IInputStream*)SocketInput_.Get()));
}
THttpInput& GetStream() override {
- return *HttpInput;
+ return *HttpInput_;
}
unsigned GetRetCode() override {
- return ParseHttpRetCode(HttpInput->FirstLine());
+ return ParseHttpRetCode(HttpInput_->FirstLine());
}
THttpURL GetRedirectURL(const THttpURL& baseUrl) override {
- for (auto i = HttpInput->Headers().Begin(); i != HttpInput->Headers().End(); ++i) {
+ for (auto i = HttpInput_->Headers().Begin(); i != HttpInput_->Headers().End(); ++i) {
if (0 == TCiString::compare(i->Name(), TStringBuf("location"))) {
THttpURL target = ParseURL(i->Value(), THttpURL::FeaturesAll | NUri::TFeature::FeatureConvertHostIDN);
if (!target.IsValidAbs()) {
@@ -107,11 +107,11 @@ public:
}
private:
- THolder<TSocket> Socket;
- THolder<TSocketInput> SocketInput;
- THolder<TSocketOutput> SocketOutput;
- THolder<TOpenSslClientIO> Ssl;
- THolder<THttpInput> HttpInput;
+ THolder<TSocket> Socket_;
+ THolder<TSocketInput> SocketInput_;
+ THolder<TSocketOutput> SocketOutput_;
+ THolder<TOpenSslClientIO> Ssl_;
+ THolder<THttpInput> HttpInput_;
};
inline bool IsRedirectCode(unsigned code) {
diff --git a/yql/essentials/utils/log/log.cpp b/yql/essentials/utils/log/log.cpp
index fc63913c750..519b9aabe9e 100644
--- a/yql/essentials/utils/log/log.cpp
+++ b/yql/essentials/utils/log/log.cpp
@@ -26,9 +26,9 @@ namespace {
class TLimitedLogBackend final : public TLogBackend {
public:
TLimitedLogBackend(TAutoPtr<TLogBackend> b, TAtomic& flag, ui64 limit) noexcept
- : Backend(b)
- , Flag(flag)
- , Limit(limit)
+ : Backend_(b)
+ , Flag_(flag)
+ , Limit_(limit)
{
}
@@ -36,24 +36,24 @@ public:
}
void ReopenLog() final {
- Backend->ReopenLog();
+ Backend_->ReopenLog();
}
void WriteData(const TLogRecord& rec) final {
- const auto remaining = AtomicGet(Limit);
- const bool final = remaining > 0 && AtomicSub(Limit, rec.Len) <= 0;
+ const auto remaining = AtomicGet(Limit_);
+ const bool final = remaining > 0 && AtomicSub(Limit_, rec.Len) <= 0;
if (remaining > 0 || rec.Priority <= TLOG_WARNING) {
- Backend->WriteData(rec);
+ Backend_->WriteData(rec);
}
if (final) {
- AtomicSet(Flag, 1);
+ AtomicSet(Flag_, 1);
}
}
private:
- THolder<TLogBackend> Backend;
- TAtomic& Flag;
- TAtomic Limit;
+ THolder<TLogBackend> Backend_;
+ TAtomic& Flag_;
+ TAtomic Limit_;
};
class TEmergencyLogOutput: public IOutputStream {
diff --git a/yql/essentials/utils/multi_resource_lock.h b/yql/essentials/utils/multi_resource_lock.h
index 61804fa9a49..c7f4ea49e27 100644
--- a/yql/essentials/utils/multi_resource_lock.h
+++ b/yql/essentials/utils/multi_resource_lock.h
@@ -18,7 +18,7 @@ private:
return RefCount() == 1;
}
- TMutex Mutex_;
+ TMutex Mutex;
};
public:
@@ -29,7 +29,7 @@ public:
, ResourceId_(std::move(resourceId))
{
Y_ENSURE(Lock_);
- Lock_->Mutex_.Acquire();
+ Lock_->Mutex.Acquire();
}
TResourceLock(TResourceLock&& other)
@@ -47,7 +47,7 @@ public:
return;
}
- Lock_->Mutex_.Release();
+ Lock_->Mutex.Release();
// decrement ref count before TryCleanup
Lock_ = nullptr;
Owner_.TryCleanup(ResourceId_);
diff --git a/yql/essentials/utils/oom_helper/inject.cpp b/yql/essentials/utils/oom_helper/inject.cpp
index 089d1a3b24f..e0b6a2e0c8e 100644
--- a/yql/essentials/utils/oom_helper/inject.cpp
+++ b/yql/essentials/utils/oom_helper/inject.cpp
@@ -11,7 +11,7 @@
#define UNIT SYSCALL_MMAP2_UNIT
#define OFF_MASK ((-0x2000ULL << (8*sizeof(long)-1)) | (UNIT-1))
-void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
+void *Mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
{
void* ret = (void*)-1;
if (off & OFF_MASK) {
@@ -39,7 +39,7 @@ void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
{
- auto res = __mmap(start, len, prot, flags, fd, off);
+ auto res = Mmap(start, len, prot, flags, fd, off);
if (res == (void*) -1 && errno == ENOMEM) {
fprintf(stderr, "mmap failed with ENOMEM\n");
_exit(2);
diff --git a/yql/essentials/utils/signals/signals.cpp b/yql/essentials/utils/signals/signals.cpp
index 45e199e95f4..bb22e266240 100644
--- a/yql/essentials/utils/signals/signals.cpp
+++ b/yql/essentials/utils/signals/signals.cpp
@@ -128,8 +128,8 @@ int SetSignalHandler(int signo, void (*handler)(int))
struct TSignalHandlerDesc
{
- int signo;
- void (*handler)(int);
+ int Signo;
+ void (*Handler)(int);
};
void SetSignalHandlers(const TSignalHandlerDesc* handlerDescs)
@@ -137,11 +137,11 @@ void SetSignalHandlers(const TSignalHandlerDesc* handlerDescs)
sigset_t interestedSignals;
SigEmptySet(&interestedSignals);
- for (int i = 0; handlerDescs[i].signo != -1; i++) {
- int signo = handlerDescs[i].signo;
+ for (int i = 0; handlerDescs[i].Signo != -1; i++) {
+ int signo = handlerDescs[i].Signo;
SigAddSet(&interestedSignals, signo);
- if (SetSignalHandler(signo, handlerDescs[i].handler) == -1) {
+ if (SetSignalHandler(signo, handlerDescs[i].Handler) == -1) {
ythrow TSystemError() << "Cannot set handler for signal "
<< strsignal(signo);
}
diff --git a/yql/essentials/utils/sys/linux_version.h b/yql/essentials/utils/sys/linux_version.h
index c8c32da125c..7ae893d257d 100644
--- a/yql/essentials/utils/sys/linux_version.h
+++ b/yql/essentials/utils/sys/linux_version.h
@@ -9,5 +9,5 @@ namespace NYql {
// returns version, patch level
std::pair<int, int> DetectLinuxKernelVersion2();
- bool IsLinuxKernelBelow4_3();
+ bool IsLinuxKernelBelow4_3(); // NOLINT(readability-identifier-naming)
}
diff --git a/yql/essentials/utils/url_builder.cpp b/yql/essentials/utils/url_builder.cpp
index 31344fbb221..e8a55561e84 100644
--- a/yql/essentials/utils/url_builder.cpp
+++ b/yql/essentials/utils/url_builder.cpp
@@ -5,12 +5,12 @@
namespace NYql {
TUrlBuilder::TUrlBuilder(const TString& uri)
- : MainUri(uri)
+ : MainUri_(uri)
{
}
TUrlBuilder& TUrlBuilder::AddUrlParam(const TString& name, const TString& value) {
- Params.emplace_back(TParam {name, value});
+ Params_.emplace_back(TParam {name, value});
return *this;
}
@@ -19,25 +19,25 @@ TUrlBuilder& TUrlBuilder::AddPathComponent(const TString& value) {
throw yexception() << "Empty path component is not allowed";
}
TStringBuilder res;
- res << MainUri;
- if (!MainUri.EndsWith('/')) {
+ res << MainUri_;
+ if (!MainUri_.EndsWith('/')) {
res << '/';
}
res << UrlEscapeRet(value, true);
- MainUri = std::move(res);
+ MainUri_ = std::move(res);
return *this;
}
TString TUrlBuilder::Build() const {
- if (Params.empty()) {
- return MainUri;
+ if (Params_.empty()) {
+ return MainUri_;
}
TStringBuilder res;
- res << MainUri << "?";
+ res << MainUri_ << "?";
TStringBuf separator = ""sv;
- for (const auto& p : Params) {
+ for (const auto& p : Params_) {
res << separator << p.Name;
if (p.Value) {
res << "=" << CGIEscapeRet(p.Value);
diff --git a/yql/essentials/utils/url_builder.h b/yql/essentials/utils/url_builder.h
index 774bc3bcd86..c4d4cfb7854 100644
--- a/yql/essentials/utils/url_builder.h
+++ b/yql/essentials/utils/url_builder.h
@@ -19,8 +19,8 @@ public:
TString Build() const;
private:
- std::vector<TParam> Params;
- TString MainUri;
+ std::vector<TParam> Params_;
+ TString MainUri_;
};
} // NYql
diff --git a/yt/yt/client/api/chaos_client.h b/yt/yt/client/api/chaos_client.h
new file mode 100644
index 00000000000..c0caafd1fe0
--- /dev/null
+++ b/yt/yt/client/api/chaos_client.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "prerequisite.h"
+#include "prerequisite_client.h"
+
+#include <yt/yt/client/chaos_client/public.h>
+
+namespace NYT::NApi {
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct TChaosLeaseStartOptions
+ : public TPrerequisiteAttachOptions
+{
+ std::optional<TDuration> LeaseTimeout;
+
+ NChaosClient::TChaosLeaseId ParentId;
+
+ NYTree::IAttributeDictionaryPtr Attributes;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct TChaosLeaseAttachOptions
+ : public TPrerequisiteAttachOptions
+{ };
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct IChaosClient
+{
+ virtual ~IChaosClient() = default;
+
+ virtual TFuture<IPrerequisitePtr> StartChaosLease(const TChaosLeaseStartOptions& options = {}) = 0;
+
+ virtual TFuture<IPrerequisitePtr> AttachChaosLease(
+ NChaosClient::TChaosLeaseId chaosLeaseId,
+ const TChaosLeaseAttachOptions& options = {}) = 0;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NApi
diff --git a/yt/yt/client/api/chaos_lease_base.cpp b/yt/yt/client/api/chaos_lease_base.cpp
new file mode 100644
index 00000000000..8a9db89fc7d
--- /dev/null
+++ b/yt/yt/client/api/chaos_lease_base.cpp
@@ -0,0 +1,136 @@
+#include "chaos_lease_base.h"
+
+#include "connection.h"
+#include "client.h"
+
+#include <yt/yt/core/rpc/public.h>
+
+namespace NYT::NApi {
+
+////////////////////////////////////////////////////////////////////////////////
+
+TChaosLeaseBase::TChaosLeaseBase(
+ IClientPtr client,
+ NRpc::IChannelPtr channel,
+ NChaosClient::TChaosLeaseId id,
+ TDuration timeout,
+ bool pingAncestors,
+ std::optional<TDuration> pingPeriod,
+ const NLogging::TLogger& logger)
+ : Client_(std::move(client))
+ , Channel_(std::move(channel))
+ , Id_(id)
+ , Timeout_(timeout)
+ , PingAncestors_(pingAncestors)
+ , PingPeriod_(pingPeriod)
+ , Logger(logger.WithTag("ChaosLease: %v, %v",
+ Id_,
+ Client_->GetConnection()->GetLoggingTag()))
+{ }
+
+NApi::IClientPtr TChaosLeaseBase::GetClient() const
+{
+ return Client_;
+}
+
+NPrerequisiteClient::TPrerequisiteId TChaosLeaseBase::GetId() const
+{
+ return Id_;
+}
+
+TDuration TChaosLeaseBase::GetTimeout() const
+{
+ return Timeout_;
+}
+
+TFuture<void> TChaosLeaseBase::Ping(const TPrerequisitePingOptions& options)
+{
+ return DoPing(options).Apply(
+ BIND([=, this, this_ = MakeStrong(this)] (const TErrorOr<void>& resultOrError) {
+ if (resultOrError.IsOK()) {
+ YT_LOG_DEBUG("Chaos lease pinged");
+ } else if (resultOrError.FindMatching(NChaosClient::EErrorCode::ChaosLeaseNotKnown)) {
+ // Hard error.
+ YT_LOG_DEBUG("Chaos lease has expired or was aborted");
+
+ {
+ auto guard = Guard(SpinLock_);
+ if (!Aborted_.IsFired()) {
+ Aborted_.Fire(resultOrError);
+ }
+ }
+
+ THROW_ERROR(resultOrError);
+ } else {
+ // Soft error.
+ YT_LOG_DEBUG(resultOrError, "Error pinging chaos lease");
+
+ THROW_ERROR_EXCEPTION("Error pinging chaos lease %v",
+ GetId())
+ << resultOrError;
+ }
+ }));
+}
+
+TFuture<void> TChaosLeaseBase::Abort(const TPrerequisiteAbortOptions& options)
+{
+ {
+ auto guard = Guard(SpinLock_);
+ if (AbortPromise_) {
+ return AbortPromise_.ToFuture();
+ }
+
+ AbortPromise_ = NewPromise<void>();
+ }
+
+ auto chaosLeasePath = Format("#%v", GetId());
+ auto removeOptions = TRemoveNodeOptions{
+ .Force = options.Force,
+ };
+ return Client_->RemoveNode(chaosLeasePath, removeOptions)
+ .Apply(BIND([=, this, this_ = MakeStrong(this)] (const TErrorOr<void>& rspOrError) {
+ {
+ auto guard = Guard(SpinLock_);
+
+ if (!AbortPromise_) {
+ YT_LOG_DEBUG(rspOrError, "Chaos lease is no longer aborting, abort response ignored");
+ return;
+ }
+
+ TError abortError;
+ if (rspOrError.IsOK()) {
+ YT_LOG_DEBUG("Chaos lease aborted");
+ } else {
+ YT_LOG_DEBUG(rspOrError, "Error aborting chaos lease");
+
+ abortError = TError("Error aborting chaos lease %v",
+ GetId())
+ << rspOrError;
+ }
+
+ auto abortPromise = std::exchange(AbortPromise_, TPromise<void>());
+
+ if (abortError.IsOK() && !Aborted_.IsFired()) {
+ Aborted_.Fire(TError("Chaos lease aborted by user request"));
+ }
+
+ guard.Release();
+
+ abortPromise.Set(std::move(abortError));
+ }
+ }));
+}
+
+void TChaosLeaseBase::SubscribeAborted(const TAbortedHandler& handler)
+{
+ Aborted_.Subscribe(handler);
+}
+
+void TChaosLeaseBase::UnsubscribeAborted(const TAbortedHandler& handler)
+{
+ Aborted_.Unsubscribe(handler);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NApi
diff --git a/yt/yt/client/api/chaos_lease_base.h b/yt/yt/client/api/chaos_lease_base.h
new file mode 100644
index 00000000000..4029a98851b
--- /dev/null
+++ b/yt/yt/client/api/chaos_lease_base.h
@@ -0,0 +1,58 @@
+#pragma once
+
+#include "private.h"
+
+#include "prerequisite.h"
+
+#include <yt/yt/core/rpc/public.h>
+
+#include <yt/yt/client/api/public.h>
+
+namespace NYT::NApi {
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TChaosLeaseBase
+ : public virtual IPrerequisite
+{
+public:
+ TChaosLeaseBase(
+ IClientPtr client,
+ NRpc::IChannelPtr channel,
+ NChaosClient::TChaosLeaseId id,
+ TDuration timeout,
+ bool pingAncestors,
+ std::optional<TDuration> pingPeriod,
+ const NLogging::TLogger& logger);
+
+ NApi::IClientPtr GetClient() const override;
+ NPrerequisiteClient::TPrerequisiteId GetId() const override;
+ TDuration GetTimeout() const override;
+
+ TFuture<void> Ping(const TPrerequisitePingOptions& options = {}) override;
+ TFuture<void> Abort(const TPrerequisiteAbortOptions& options = {}) override;
+
+ void SubscribeAborted(const TAbortedHandler& handler) override;
+ void UnsubscribeAborted(const TAbortedHandler& handler) override;
+
+protected:
+ const IClientPtr Client_;
+ const NRpc::IChannelPtr Channel_;
+ const NChaosClient::TChaosLeaseId Id_;
+ const TDuration Timeout_;
+ const bool PingAncestors_;
+ const std::optional<TDuration> PingPeriod_;
+
+ const NLogging::TLogger Logger;
+
+ YT_DECLARE_SPIN_LOCK(NThreading::TSpinLock, SpinLock_);
+ TPromise<void> AbortPromise_;
+
+ TSingleShotCallbackList<TAbortedHandlerSignature> Aborted_;
+
+ virtual TFuture<void> DoPing(const TPrerequisitePingOptions& options) = 0;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NApi::NRpcProxy
diff --git a/yt/yt/client/api/client.h b/yt/yt/client/api/client.h
index 713c524a1d0..97b6c95df3b 100644
--- a/yt/yt/client/api/client.h
+++ b/yt/yt/client/api/client.h
@@ -3,6 +3,7 @@
#include "accounting_client.h"
#include "admin_client.h"
#include "connection.h"
+#include "chaos_client.h"
#include "cypress_client.h"
#include "distributed_table_client.h"
#include "etc_client.h"
@@ -61,6 +62,7 @@ DEFINE_REFCOUNTED_TYPE(IClientBase)
*/
struct IClient
: public virtual IClientBase
+ , public IChaosClient
, public IPrerequisiteClient
, public ITransactionClient
, public ITableClient
diff --git a/yt/yt/client/api/delegating_client.h b/yt/yt/client/api/delegating_client.h
index 4aec618c1c7..8ce31e05185 100644
--- a/yt/yt/client/api/delegating_client.h
+++ b/yt/yt/client/api/delegating_client.h
@@ -331,6 +331,15 @@ public:
const TAlterReplicationCardOptions& options),
(replicationCardId, options))
+ DELEGATE_METHOD(TFuture<IPrerequisitePtr>, StartChaosLease, (
+ const TChaosLeaseStartOptions& options),
+ (options));
+
+ DELEGATE_METHOD(TFuture<IPrerequisitePtr>, AttachChaosLease, (
+ NChaosClient::TChaosLeaseId chaosLeaseId,
+ const TChaosLeaseAttachOptions& options),
+ (chaosLeaseId, options));
+
DELEGATE_METHOD(TFuture<NYson::TYsonString>, GetTablePivotKeys, (
const NYPath::TYPath& path,
const TGetTablePivotKeysOptions& options),
diff --git a/yt/yt/client/api/prerequisite.h b/yt/yt/client/api/prerequisite.h
index 229cca00f82..684e004081f 100644
--- a/yt/yt/client/api/prerequisite.h
+++ b/yt/yt/client/api/prerequisite.h
@@ -35,8 +35,6 @@ struct IPrerequisite
virtual TFuture<void> Ping(const TPrerequisitePingOptions& options = {}) = 0;
virtual TFuture<void> Abort(const TPrerequisiteAbortOptions& options = {}) = 0;
- virtual void Detach() = 0;
-
virtual NPrerequisiteClient::TPrerequisiteId GetId() const = 0;
//! Verified dynamic casts to a more specific interface.
diff --git a/yt/yt/client/api/prerequisite_client.h b/yt/yt/client/api/prerequisite_client.h
index dfe5be31e4c..d190f50fb7d 100644
--- a/yt/yt/client/api/prerequisite_client.h
+++ b/yt/yt/client/api/prerequisite_client.h
@@ -7,6 +7,7 @@ namespace NYT::NApi {
////////////////////////////////////////////////////////////////////////////////
struct TPrerequisiteAttachOptions
+ : public TTimeoutOptions
{
bool AutoAbort = false;
std::optional<TDuration> PingPeriod;
diff --git a/yt/yt/client/api/public.h b/yt/yt/client/api/public.h
index 19d31ab9c38..624bf2fcd33 100644
--- a/yt/yt/client/api/public.h
+++ b/yt/yt/client/api/public.h
@@ -1,5 +1,7 @@
#pragma once
+#include <yt/yt/client/chaos_client/public.h>
+
#include <yt/yt/client/object_client/public.h>
#include <yt/yt/client/table_client/public.h>
diff --git a/yt/yt/client/api/rpc_proxy/api_service_proxy.h b/yt/yt/client/api/rpc_proxy/api_service_proxy.h
index 9a64989204a..611ca495104 100644
--- a/yt/yt/client/api/rpc_proxy/api_service_proxy.h
+++ b/yt/yt/client/api/rpc_proxy/api_service_proxy.h
@@ -83,6 +83,7 @@ public:
// Chaos
DEFINE_RPC_PROXY_METHOD(NRpcProxy::NProto, AlterReplicationCard);
+ DEFINE_RPC_PROXY_METHOD(NRpcProxy::NProto, PingChaosLease);
// Queues
// COMPAT(nadya73): For compatability with old versions of clients.
diff --git a/yt/yt/client/api/rpc_proxy/chaos_lease.cpp b/yt/yt/client/api/rpc_proxy/chaos_lease.cpp
new file mode 100644
index 00000000000..46906be8367
--- /dev/null
+++ b/yt/yt/client/api/rpc_proxy/chaos_lease.cpp
@@ -0,0 +1,75 @@
+#include "chaos_lease.h"
+
+#include "client_impl.h"
+#include "private.h"
+
+#include <yt/yt/client/api/chaos_lease_base.h>
+
+#include <yt/yt/core/rpc/public.h>
+
+namespace NYT::NApi::NRpcProxy {
+
+////////////////////////////////////////////////////////////////////////////////
+
+class TChaosLease
+ : public TChaosLeaseBase
+{
+public:
+ TChaosLease(
+ IClientPtr client,
+ NRpc::IChannelPtr channel,
+ NChaosClient::TChaosLeaseId chaosLeaseId,
+ TDuration timeout,
+ bool pingAncestors,
+ std::optional<TDuration> pingPeriod)
+ : TChaosLeaseBase(
+ std::move(client),
+ std::move(channel),
+ chaosLeaseId,
+ timeout,
+ pingAncestors,
+ pingPeriod,
+ RpcProxyClientLogger())
+ , Proxy_(Channel_)
+ { }
+
+ TFuture<void> DoPing(const TPrerequisitePingOptions& /*options*/) override
+ {
+ auto req = Proxy_.PingChaosLease();
+ // TODO(gryzlov-ad): Put correct timeout here.
+ req->SetTimeout(NRpc::DefaultRpcRequestTimeout);
+
+ ToProto(req->mutable_chaos_lease_id(), GetId());
+ req->set_ping_ancestors(PingAncestors_);
+
+ return req->Invoke().AsVoid();
+ }
+
+private:
+ TApiServiceProxy Proxy_;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
+IPrerequisitePtr CreateChaosLease(
+ IClientPtr client,
+ NRpc::IChannelPtr channel,
+ NChaosClient::TChaosLeaseId chaosLeaseId,
+ TDuration timeout,
+ bool pingAncestors,
+ std::optional<TDuration> pingPeriod)
+{
+ auto chaosLease = New<TChaosLease>(
+ std::move(client),
+ std::move(channel),
+ chaosLeaseId,
+ timeout,
+ pingAncestors,
+ pingPeriod);
+
+ return chaosLease;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NApi::NRpcProxy
diff --git a/yt/yt/client/api/rpc_proxy/chaos_lease.h b/yt/yt/client/api/rpc_proxy/chaos_lease.h
new file mode 100644
index 00000000000..f2d3e43ff69
--- /dev/null
+++ b/yt/yt/client/api/rpc_proxy/chaos_lease.h
@@ -0,0 +1,19 @@
+#pragma once
+
+#include <yt/yt/client/api/public.h>
+
+namespace NYT::NApi::NRpcProxy {
+
+////////////////////////////////////////////////////////////////////////////////
+
+NApi::IPrerequisitePtr CreateChaosLease(
+ IClientPtr client,
+ NRpc::IChannelPtr channel,
+ NChaosClient::TChaosLeaseId id,
+ TDuration timeout,
+ bool pingAncestors,
+ std::optional<TDuration> pingPeriod);
+
+////////////////////////////////////////////////////////////////////////////////
+
+} // namespace NYT::NApi::NRpcProxy
diff --git a/yt/yt/client/api/rpc_proxy/client_impl.cpp b/yt/yt/client/api/rpc_proxy/client_impl.cpp
index 1efb024acbe..f1861a953a3 100644
--- a/yt/yt/client/api/rpc_proxy/client_impl.cpp
+++ b/yt/yt/client/api/rpc_proxy/client_impl.cpp
@@ -1,6 +1,7 @@
#include "client_impl.h"
#include "config.h"
+#include "chaos_lease.h"
#include "helpers.h"
#include "private.h"
#include "row_batch_reader.h"
@@ -27,6 +28,8 @@
#include <yt/yt/client/table_client/unversioned_row.h>
#include <yt/yt/client/table_client/wire_protocol.h>
+#include <yt/yt/client/object_client/helpers.h>
+
#include <yt/yt/client/api/distributed_table_session.h>
#include <yt/yt/client/ypath/rich.h>
@@ -237,6 +240,64 @@ ITransactionPtr TClient::AttachTransaction(
"Transaction attached");
}
+TFuture<IPrerequisitePtr> TClient::AttachChaosLease(
+ TChaosLeaseId chaosLeaseId,
+ const TChaosLeaseAttachOptions& options)
+{
+ auto connection = GetRpcProxyConnection();
+ auto client = GetRpcProxyClient();
+ auto channel = GetRetryingChannel();
+
+ auto chaosLeasePath = Format("#%v/@", chaosLeaseId);
+
+ return client->GetNode(chaosLeasePath, {}).Apply(BIND([=](const TYsonString& value) {
+ auto attributes = ConvertToAttributes(value);
+ auto timeoutValue = attributes->Get<i64>("timeout");
+ auto timeout = TDuration::MilliSeconds(timeoutValue);
+
+ auto chaosLease = CreateChaosLease(
+ std::move(client),
+ std::move(channel),
+ chaosLeaseId,
+ timeout,
+ options.PingAncestors,
+ options.PingPeriod);
+
+ if (options.Ping) {
+ return chaosLease->Ping({}).Apply(BIND([=] {
+ return chaosLease;
+ }));
+ }
+
+ return MakeFuture<IPrerequisitePtr>(chaosLease);
+ }));
+}
+
+TFuture<IPrerequisitePtr> TClient::StartChaosLease(const TChaosLeaseStartOptions& options)
+{
+ auto connection = GetRpcProxyConnection();
+ auto client = GetRpcProxyClient();
+ auto channel = GetRetryingChannel();
+
+ auto createOptions = TCreateNodeOptions{};
+ auto timeout = options.LeaseTimeout.value_or(connection->GetConfig()->DefaultChaosLeaseTimeout);
+ createOptions.Attributes = ConvertToAttributes(BuildYsonStringFluently()
+ .BeginMap()
+ .Item("timeout").Value(timeout)
+ .OptionalItem("parent_id", options.ParentId)
+ .EndMap());
+
+ return client->CreateObject(EObjectType::ChaosLease, {}).Apply(BIND([=](const TChaosLeaseId& chaosLeaseId) {
+ return CreateChaosLease(
+ std::move(client),
+ std::move(channel),
+ chaosLeaseId,
+ timeout,
+ options.PingAncestors,
+ options.PingPeriod);
+ }));
+}
+
IPrerequisitePtr TClient::AttachPrerequisite(
NPrerequisiteClient::TPrerequisiteId prerequisiteId,
const TPrerequisiteAttachOptions& options)
diff --git a/yt/yt/client/api/rpc_proxy/client_impl.h b/yt/yt/client/api/rpc_proxy/client_impl.h
index 27a5df9a2f5..ce13d5cc284 100644
--- a/yt/yt/client/api/rpc_proxy/client_impl.h
+++ b/yt/yt/client/api/rpc_proxy/client_impl.h
@@ -125,6 +125,7 @@ public:
const std::vector<NYPath::TYPath>& movableTables,
const NApi::TBalanceTabletCellsOptions& options) override;
+ // Chaos.
TFuture<NChaosClient::TReplicationCardPtr> GetReplicationCard(
NChaosClient::TReplicationCardId replicationCardId,
const TGetReplicationCardOptions& options = {}) override;
@@ -137,6 +138,13 @@ public:
NChaosClient::TReplicationCardId replicationCardId,
const TAlterReplicationCardOptions& options = {}) override;
+ TFuture<NApi::IPrerequisitePtr> AttachChaosLease(
+ NChaosClient::TChaosLeaseId chaosLeaseId,
+ const TChaosLeaseAttachOptions& options = {}) override;
+
+ TFuture<NApi::IPrerequisitePtr> StartChaosLease(
+ const TChaosLeaseStartOptions& options = {}) override;
+
// Distributed table client
TFuture<ITableFragmentWriterPtr> CreateTableFragmentWriter(
const TSignedWriteFragmentCookiePtr& cookie,
diff --git a/yt/yt/client/api/rpc_proxy/config.cpp b/yt/yt/client/api/rpc_proxy/config.cpp
index 5d39bec379b..478201122e0 100644
--- a/yt/yt/client/api/rpc_proxy/config.cpp
+++ b/yt/yt/client/api/rpc_proxy/config.cpp
@@ -84,6 +84,8 @@ void TConnectionConfig::Register(TRegistrar registrar)
.Default(TDuration::Minutes(15));
registrar.Parameter("default_streaming_stall_timeout", &TThis::DefaultStreamingStallTimeout)
.Default(TDuration::Minutes(1));
+ registrar.Parameter("default_chaos_lease_timeout", &TThis::DefaultChaosLeaseTimeout)
+ .Default(TDuration::Seconds(30));
registrar.Parameter("default_ping_period", &TThis::DefaultPingPeriod)
.Default(TDuration::Seconds(5));
diff --git a/yt/yt/client/api/rpc_proxy/config.h b/yt/yt/client/api/rpc_proxy/config.h
index bbac7614512..187fbf83231 100644
--- a/yt/yt/client/api/rpc_proxy/config.h
+++ b/yt/yt/client/api/rpc_proxy/config.h
@@ -58,6 +58,7 @@ struct TConnectionConfig
TDuration DefaultTotalStreamingTimeout;
TDuration DefaultStreamingStallTimeout;
TDuration DefaultPingPeriod;
+ TDuration DefaultChaosLeaseTimeout;
NBus::TBusConfigPtr BusClient;
TDuration IdleChannelTtl;
diff --git a/yt/yt/client/api/transaction.h b/yt/yt/client/api/transaction.h
index 5a20f09c240..debca7ce828 100644
--- a/yt/yt/client/api/transaction.h
+++ b/yt/yt/client/api/transaction.h
@@ -121,6 +121,8 @@ struct ITransaction
virtual TFuture<TTransactionCommitResult> Commit(const TTransactionCommitOptions& options = {}) = 0;
+ virtual void Detach() = 0;
+
virtual TFuture<void> Abort(const TPrerequisiteAbortOptions& options = {}) override;
virtual TFuture<void> Abort(const TTransactionAbortOptions& options) = 0;
diff --git a/yt/yt/client/chaos_client/public.h b/yt/yt/client/chaos_client/public.h
index 5c50d3a806e..6af7ebcd06d 100644
--- a/yt/yt/client/chaos_client/public.h
+++ b/yt/yt/client/chaos_client/public.h
@@ -42,6 +42,7 @@ YT_DEFINE_ERROR_ENUM(
((ChaosCellSuspended) (3202))
((ReplicationCollocationNotKnown) (3203))
((ReplicationCollocationIsMigrating) (3204))
+ ((ChaosLeaseNotKnown) (3205))
);
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/client/driver/chaos_commands.cpp b/yt/yt/client/driver/chaos_commands.cpp
index 72b67dc19db..a2f41ce37cf 100644
--- a/yt/yt/client/driver/chaos_commands.cpp
+++ b/yt/yt/client/driver/chaos_commands.cpp
@@ -85,4 +85,24 @@ void TAlterReplicationCardCommand::DoExecute(ICommandContextPtr context)
////////////////////////////////////////////////////////////////////////////////
+void TPingChaosLeaseCommand::Register(TRegistrar registrar)
+{
+ registrar.Parameter("chaos_lease_id", &TThis::ChaosLeaseId);
+}
+
+void TPingChaosLeaseCommand::DoExecute(ICommandContextPtr context)
+{
+ auto options = TChaosLeaseAttachOptions{};
+ options.Ping = true;
+ options.PingAncestors = true;
+
+ auto future = context->GetClient()->AttachChaosLease(ChaosLeaseId, options);
+ auto chaosLease = WaitFor(future)
+ .ValueOrThrow();
+
+ ProduceEmptyOutput(context);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace NYT::NDriver
diff --git a/yt/yt/client/driver/chaos_commands.h b/yt/yt/client/driver/chaos_commands.h
index ac50bcf643d..dd95ef4658e 100644
--- a/yt/yt/client/driver/chaos_commands.h
+++ b/yt/yt/client/driver/chaos_commands.h
@@ -42,4 +42,20 @@ private:
////////////////////////////////////////////////////////////////////////////////
+class TPingChaosLeaseCommand
+ : public TTypedCommand<NApi::TPrerequisitePingOptions>
+{
+public:
+ REGISTER_YSON_STRUCT_LITE(TPingChaosLeaseCommand);
+
+ static void Register(TRegistrar registrar);
+
+private:
+ NChaosClient::TChaosLeaseId ChaosLeaseId;
+
+ void DoExecute(ICommandContextPtr context) override;
+};
+
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace NYT::NDriver
diff --git a/yt/yt/client/driver/driver.cpp b/yt/yt/client/driver/driver.cpp
index 56d7d099aac..3a31bf69cd1 100644
--- a/yt/yt/client/driver/driver.cpp
+++ b/yt/yt/client/driver/driver.cpp
@@ -256,6 +256,7 @@ public:
REGISTER (TUpdateChaosTableReplicaProgressCommand, "update_replication_progress", Null, Structured, false, false, ApiVersion4);
REGISTER (TAlterReplicationCardCommand, "alter_replication_card", Null, Structured, false, false, ApiVersion4);
+ REGISTER (TPingChaosLeaseCommand, "ping_chaos_lease", Null, Structured, true, false, ApiVersion4);
REGISTER (TMergeCommand, "merge", Null, Structured, true, false, ApiVersion3);
REGISTER (TEraseCommand, "erase", Null, Structured, true, false, ApiVersion3);
diff --git a/yt/yt/client/federated/client.cpp b/yt/yt/client/federated/client.cpp
index 361e1992a4b..da3cb8f0bea 100644
--- a/yt/yt/client/federated/client.cpp
+++ b/yt/yt/client/federated/client.cpp
@@ -396,6 +396,8 @@ public:
UNIMPLEMENTED_METHOD(TFuture<void>, AlterTable, (const NYPath::TYPath&, const TAlterTableOptions&));
UNIMPLEMENTED_METHOD(TFuture<void>, AlterTableReplica, (NTabletClient::TTableReplicaId, const TAlterTableReplicaOptions&));
UNIMPLEMENTED_METHOD(TFuture<void>, AlterReplicationCard, (NChaosClient::TReplicationCardId, const TAlterReplicationCardOptions&));
+ UNIMPLEMENTED_METHOD(TFuture<IPrerequisitePtr>, StartChaosLease, (const TChaosLeaseStartOptions&));
+ UNIMPLEMENTED_METHOD(TFuture<IPrerequisitePtr>, AttachChaosLease, (NChaosClient::TChaosLeaseId, const TChaosLeaseAttachOptions&));
UNIMPLEMENTED_METHOD(TFuture<std::vector<NTabletClient::TTableReplicaId>>, GetInSyncReplicas, (const NYPath::TYPath&, const NTableClient::TNameTablePtr&, const TSharedRange<NTableClient::TUnversionedRow>&, const TGetInSyncReplicasOptions&));
UNIMPLEMENTED_METHOD(TFuture<std::vector<NTabletClient::TTableReplicaId>>, GetInSyncReplicas, (const NYPath::TYPath&, const TGetInSyncReplicasOptions&));
UNIMPLEMENTED_METHOD(TFuture<TGetTabletErrorsResult>, GetTabletErrors, (const NYPath::TYPath&, const TGetTabletErrorsOptions&));
diff --git a/yt/yt/client/hedging/hedging.cpp b/yt/yt/client/hedging/hedging.cpp
index 0dfd4b1f7ae..420326ad4c4 100644
--- a/yt/yt/client/hedging/hedging.cpp
+++ b/yt/yt/client/hedging/hedging.cpp
@@ -134,6 +134,8 @@ public:
UNSUPPORTED_METHOD(TFuture<void>, AlterTable, (const TYPath&, const TAlterTableOptions&));
UNSUPPORTED_METHOD(TFuture<void>, AlterTableReplica, (NTabletClient::TTableReplicaId, const TAlterTableReplicaOptions&));
UNSUPPORTED_METHOD(TFuture<void>, AlterReplicationCard, (NChaosClient::TReplicationCardId, const TAlterReplicationCardOptions&));
+ UNSUPPORTED_METHOD(TFuture<IPrerequisitePtr>, StartChaosLease, (const TChaosLeaseStartOptions&));
+ UNSUPPORTED_METHOD(TFuture<IPrerequisitePtr>, AttachChaosLease, (NChaosClient::TChaosLeaseId, const TChaosLeaseAttachOptions&));
UNSUPPORTED_METHOD(TFuture<std::vector<NTabletClient::TTableReplicaId>>, GetInSyncReplicas, (const TYPath&, const NTableClient::TNameTablePtr&, const TSharedRange<NTableClient::TUnversionedRow>&, const TGetInSyncReplicasOptions&));
UNSUPPORTED_METHOD(TFuture<std::vector<NTabletClient::TTableReplicaId>>, GetInSyncReplicas, (const TYPath&, const TGetInSyncReplicasOptions&));
UNSUPPORTED_METHOD(TFuture<std::vector<TTabletInfo>>, GetTabletInfos, (const TYPath&, const std::vector<int>&, const TGetTabletInfosOptions&));
diff --git a/yt/yt/client/unittests/mock/client.h b/yt/yt/client/unittests/mock/client.h
index 171c9dcba5c..c8009d65816 100644
--- a/yt/yt/client/unittests/mock/client.h
+++ b/yt/yt/client/unittests/mock/client.h
@@ -913,6 +913,15 @@ public:
const TShuffleWriterOptions& options),
(override));
+ MOCK_METHOD(TFuture<IPrerequisitePtr>, StartChaosLease, (
+ const TChaosLeaseStartOptions& options),
+ (override));
+
+ MOCK_METHOD(TFuture<IPrerequisitePtr>, AttachChaosLease, (
+ NChaosClient::TChaosLeaseId chaosLeaseId,
+ const TChaosLeaseAttachOptions& options),
+ (override));
+
private:
NTabletClient::ITableMountCachePtr TableMountCache_;
NTransactionClient::ITimestampProviderPtr TimestampProvider_;
diff --git a/yt/yt/client/ya.make b/yt/yt/client/ya.make
index 224cc1ba304..9a00da36c67 100644
--- a/yt/yt/client/ya.make
+++ b/yt/yt/client/ya.make
@@ -8,6 +8,7 @@ PROTO_NAMESPACE(yt)
SRCS(
api/config.cpp
+ api/chaos_lease_base.cpp
api/client.cpp
api/client_common.cpp
api/client_cache.cpp
@@ -40,6 +41,7 @@ SRCS(
api/rpc_proxy/public.cpp
api/rpc_proxy/config.cpp
api/rpc_proxy/helpers.cpp
+ api/rpc_proxy/chaos_lease.cpp
api/rpc_proxy/client_impl.cpp
api/rpc_proxy/client_base.cpp
api/rpc_proxy/connection.cpp
diff --git a/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto b/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
index 9014cbb0963..8f2c755fa10 100644
--- a/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
+++ b/yt/yt_proto/yt/client/api/rpc_proxy/proto/api_service.proto
@@ -2051,6 +2051,17 @@ message TRspAlterReplicationCard
////////////////////////////////////////////////////////////////////////////////
+message TReqPingChaosLease
+{
+ required NYT.NProto.TGuid chaos_lease_id = 1; // NChaosClient::TChaosLeaseId
+ optional bool ping_ancestors = 2 [default = true];
+}
+
+message TRspPingChaosLease
+{ }
+
+////////////////////////////////////////////////////////////////////////////////
+
message TFetchChunkSpecConfig
{
optional int32 max_chunk_per_fetch = 1;
diff --git a/yt/yt_proto/yt/client/chaos_client/proto/chaos_lease.proto b/yt/yt_proto/yt/client/chaos_client/proto/chaos_lease.proto
deleted file mode 100644
index 970c8e7447b..00000000000
--- a/yt/yt_proto/yt/client/chaos_client/proto/chaos_lease.proto
+++ /dev/null
@@ -1,10 +0,0 @@
-package NYT.NChaosClient.NProto;
-
-import "yt_proto/yt/core/misc/proto/guid.proto";
-
-////////////////////////////////////////////////////////////////////////////////
-
-message TChaosLease
-{ }
-
-////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt_proto/yt/client/ya.make b/yt/yt_proto/yt/client/ya.make
index e799449115f..dbf44fcbc89 100644
--- a/yt/yt_proto/yt/client/ya.make
+++ b/yt/yt_proto/yt/client/ya.make
@@ -19,7 +19,6 @@ SRCS(
cell_master/proto/cell_directory.proto
chaos_client/proto/replication_card.proto
- chaos_client/proto/chaos_lease.proto
chunk_client/proto/data_statistics.proto
chunk_client/proto/chunk_meta.proto