aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralexv-smirnov <alexv-smirnov@yandex-team.ru>2022-04-11 23:25:39 +0300
committeralexv-smirnov <alexv-smirnov@yandex-team.ru>2022-04-11 23:25:39 +0300
commitdecdb0ddf85d72fc392679f744315b9d939ac990 (patch)
tree3a4621237fb157f378218756b84af20c369cd5d0
parent16e9003de4b6f1849b613c915702db3532fbe4b9 (diff)
downloadydb-decdb0ddf85d72fc392679f744315b9d939ac990.tar.gz
yql docs core moved to ydb, yql docs peerdirs yql core in ydb now
yql docs core moved to ydb, yql docs peerdirs yql core in ydb now ref:8cae83cdbcf82aa0cd4b3eedb374309fc35db97c
-rw-r--r--ydb/docs/en/core/yql/reference/toc_i.yaml2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/_includes/cast_examples.md14
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/_includes/decimal_args.md5
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/agg_list.md39
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/aggregate_by.md25
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/bool_bit.md28
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/corr_covar.md27
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/count_distinct_estimate.md27
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/histogram.md120
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/max_min_by.md40
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/percentile_median.md17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/session_start.md6
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/simple.md134
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/stddev_variance.md22
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/top_bottom.md48
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/topfreq_mode.md23
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/abs.md10
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/aggr_factory.md77
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/as_container.md38
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/as_tagged.md17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/bitops.md19
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/byteat.md18
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/callable.md24
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/coalesce.md32
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/container_literal.md36
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/current_tz.md49
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/current_utc.md16
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/data-type-literals.md51
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/ensure.md44
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/enum.md31
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/evaluate_expr_atom.md28
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/files.md62
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/find.md58
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/if.md17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/intro.md4
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/length.md20
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/max_min.md14
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/metadata.md21
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/nanvl.md19
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/optional_ops.md43
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/pickle.md19
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/random.md51
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/s_expressions.md6
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/starts_ends_with.md29
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/staticmap.md24
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/staticzip.md16
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/substring.md30
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/table_path_name_recindex.md57
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/table_row.md10
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/to_from_bytes.md15
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/variant.md34
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/weakfield.md17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/codegen.md187
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/dict.md304
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/index.md17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/json.md1150
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/list.md544
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/struct.md320
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/types.md630
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/aggregate.md17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/first_last_value.md22
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/intro.md4
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/lag_lead.md13
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/rank_dense.md29
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/row_number.md13
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/session_state.md5
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/aggregation.md29
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/basic.md92
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/codegen.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/dict.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/index.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/json.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/list.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/struct.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/toc_i.yaml13
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/types.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/builtins/window.md14
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_assets/join-YQL-06.pngbin0 -> 25080 bytes
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/Readme.txt2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/begin.md21
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/define_do.md51
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/evaluate.md76
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/alter_table.md139
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/create_table.md165
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/declare/general.md36
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/delete.md36
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/discard.md30
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/drop_table.md12
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/export_import.md61
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/as.md44
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/between.md11
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/bitcast.md15
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/case.md30
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/cast.md15
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/check-match.md45
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/concatenation.md14
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/in.md45
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/is-distinct-from.md13
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/is-null.md11
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/items-access.md27
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/lambda.md33
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/named-nodes.md93
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/operators.md87
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/tables.md71
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_by.md71
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_columns.md20
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_other_db.md8
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_type_by.md44
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md18
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/distinct.md24
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/general.md66
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/general_stream.md59
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/having.md14
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/having_stream.md14
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/rollup_cube_sets.md74
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/session_window.md66
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/insert_into.md62
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/into_result.md17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/join.md130
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/lexer.md163
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/not_yet_supported.md18
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/debug.md41
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/definition.md39
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/files.md60
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/global.md204
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/issue_protos.md0
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/ydb.md14
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/yson.md28
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/process.md127
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/reduce.md104
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/replace_into.md32
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/assume_order_by.md14
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/calc.md16
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/column_order.md25
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/commit.md17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/distinct.md19
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/execution.md20
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/folder.md44
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from.md22
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from_as_table.md17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from_select.md17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/functional_tables.md114
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/limit_offset.md23
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/order_by.md23
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/sample.md42
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/secondary_index.md30
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/temporary_table.md34
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/union_all.md42
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/union_all_rules.md5
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/view.md23
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/where.md11
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/with.md43
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/without.md16
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select_stream.md49
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/subquery.md202
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/update.md38
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/upsert_into.md27
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/use.md24
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/values.md45
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/window.md157
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/action.md11
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/alter_table.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/create_table.md1
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/declare.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/delete.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/discard.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/drop_table.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/export_import.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/expressions.md32
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/flatten.md7
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/group_by.md27
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/index.md56
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/insert_into.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/into_result.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/join.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/lexer.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/not_yet_supported.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/pragma.md13
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/process.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/reduce.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/replace_into.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/select.md50
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/select_stream.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/subquery.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/toc_i.yaml31
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/update.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/upsert_into.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/use.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/values.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/syntax/window.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/toc_m.yaml2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/toc_product.yaml9
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/cast.md71
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/containers.md24
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_datetime.md10
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_number.md19
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md27
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/json.md175
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/optional.md50
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/primitive.md120
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/special.md14
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/type_string.md74
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/_includes/tz_date_types.md19
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/cast.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/containers.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/index.md12
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/json.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/optional.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/primitive.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/special.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/toc_i.yaml17
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/types/type_string.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/histogram.md19
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/index/intro.md4
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/index/list.md13
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/string.md146
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/unicode.md82
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/url.md211
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/intro_footer.md0
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/intro_header.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/ypath_overlay.md0
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/datetime.md473
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/digest.md39
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/histogram.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/hyperscan.md127
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/index.md4
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/ip.md29
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/math.md135
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/pcre.md20
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/pire.md130
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/re2.md122
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/string.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/toc_base.yaml16
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/toc_i.yaml2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/unicode.md3
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/url.md2
-rw-r--r--ydb/docs/en/core/yql/reference/yql-core/udf/list/yson.md295
-rw-r--r--ydb/docs/ru/core/yql/reference/toc_i.yaml2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/_includes/cast_examples.md14
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/_includes/decimal_args.md4
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/agg_list.md37
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/aggregate_by.md23
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/bool_bit.md25
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/corr_covar.md25
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/count_distinct_estimate.md26
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/histogram.md113
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/max_min_by.md38
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/percentile_median.md17
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/session_start.md6
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/simple.md125
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/stddev_variance.md20
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/top_bottom.md45
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/topfreq_mode.md21
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/abs.md8
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/aggr_factory.md73
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/as_container.md36
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/as_tagged.md16
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/bitops.md17
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/byteat.md16
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/callable.md22
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/coalesce.md30
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/container_literal.md34
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/current_tz.md44
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/current_utc.md13
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/data-type-literals.md49
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/ensure.md42
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/enum.md28
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/evaluate_expr_atom.md26
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/files.md56
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/find.md51
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/if.md15
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/intro.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/length.md17
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/max_min.md12
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/metadata.md19
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/nanvl.md17
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/optional_ops.md39
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/pickle.md17
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/random.md55
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/s_expressions.md5
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/starts_ends_with.md24
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/staticmap.md23
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/staticzip.md15
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/substring.md26
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/table_path_name_recindex.md53
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/table_row.md8
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/to_from_bytes.md13
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/variant.md32
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/weakfield.md15
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/codegen.md177
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/dict.md273
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/index.md16
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/json.md1156
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/list.md542
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/struct.md304
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/types.md579
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/aggregate.md15
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/first_last_value.md20
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/intro.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/lag_lead.md11
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/rank_dense.md25
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/row_number.md11
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/session_state.md4
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/aggregation.md29
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/basic.md92
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/codegen.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/dict.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/index.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/json.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/list.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/struct.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/toc_i.yaml13
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/types.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/builtins/window.md14
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_assets/join-YQL-06.pngbin0 -> 25080 bytes
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/Readme.txt2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/begin.md19
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/define_do.md50
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/evaluate.md72
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/alter_table.md136
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/create_table.md163
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/declare/general.md35
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/delete.md35
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/discard.md30
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/drop_table.md11
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/export_import.md56
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/as.md40
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/between.md11
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/bitcast.md12
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/case.md31
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/cast.md14
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/check-match.md43
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/concatenation.md13
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/in.md44
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/is-distinct-from.md11
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/is-null.md10
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/items-access.md26
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/lambda.md32
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/named-nodes.md83
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/operators.md87
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/tables.md70
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_by.md68
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_columns.md19
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_other_db.md9
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_type_by.md41
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md16
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/distinct.md24
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/general.md67
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/general_stream.md55
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/having.md13
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/having_stream.md12
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/rollup_cube_sets.md75
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/session_window.md63
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/insert_hints.md16
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/insert_into.md47
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/into_result.md16
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/join.md130
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/lexer.md155
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/not_yet_supported.md17
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/debug.md39
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/definition.md38
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/files.md59
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/global.md216
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/issue_protos.md0
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/ydb.md13
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/yson.md27
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/process.md125
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/reduce.md103
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/replace_into.md31
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/assume_order_by.md14
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/calc.md15
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/column_order.md21
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/commit.md16
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/distinct.md20
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/execution.md19
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/folder.md44
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from.md21
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from_as_table.md16
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from_select.md17
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/functional_tables.md114
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/limit_offset.md23
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/order_by.md20
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/sample.md41
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/secondary_index.md29
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/temporary_table.md34
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/union_all.md41
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/union_all_rules.md4
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/view.md22
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/where.md10
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/with.md44
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/without.md15
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select_stream.md45
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/subquery.md199
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/update.md37
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/upsert_into.md26
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/use.md23
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/values.md43
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/window.md152
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/action.md11
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/alter_table.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/create_table.md1
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/declare.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/delete.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/discard.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/drop_table.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/export_import.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/expressions.md32
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/flatten.md7
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/group_by.md27
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/index.md55
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/insert_into.md4
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/into_result.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/join.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/lexer.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/not_yet_supported.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/pragma.md13
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/process.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/reduce.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/replace_into.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/select.md53
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/select_stream.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/subquery.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/toc_i.yaml31
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/update.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/upsert_into.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/use.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/values.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/syntax/window.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/toc_m.yaml2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/toc_product.yaml9
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/cast.md63
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/containers.md23
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_datetime.md9
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_number.md17
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md26
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/json.md173
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/optional.md49
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/primitive.md120
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/special.md14
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/type_string.md73
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/_includes/tz_date_types.md16
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/cast.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/containers.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/index.md11
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/json.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/optional.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/primitive.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/special.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/toc_i.yaml17
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/types/type_string.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/histogram.md19
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/index/intro.md4
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/index/list.md13
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/string.md86
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/unicode.md82
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/url.md193
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/intro_footer.md0
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/intro_header.md1
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/ypath_overlay.md0
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/datetime.md469
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/digest.md38
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/histogram.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/hyperscan.md127
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/index.md4
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/ip.md27
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/math.md135
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/pcre.md19
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/pire.md129
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/re2.md120
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/string.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/toc_base.yaml16
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/toc_i.yaml2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/unicode.md3
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/url.md2
-rw-r--r--ydb/docs/ru/core/yql/reference/yql-core/udf/list/yson.md273
475 files changed, 22973 insertions, 2 deletions
diff --git a/ydb/docs/en/core/yql/reference/toc_i.yaml b/ydb/docs/en/core/yql/reference/toc_i.yaml
index 227096062f4..5ecab61267f 100644
--- a/ydb/docs/en/core/yql/reference/toc_i.yaml
+++ b/ydb/docs/en/core/yql/reference/toc_i.yaml
@@ -1,2 +1,2 @@
items:
-- include: { mode: merge, path: ../../../yql/docs_yfm/docs/en/yql-core/toc_m.yaml }
+- include: { mode: merge, path: yql-core/toc_m.yaml }
diff --git a/ydb/docs/en/core/yql/reference/yql-core/_includes/cast_examples.md b/ydb/docs/en/core/yql/reference/yql-core/_includes/cast_examples.md
new file mode 100644
index 00000000000..467901871fd
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/_includes/cast_examples.md
@@ -0,0 +1,14 @@
+SELECT
+ CAST("12345" AS Double), -- 12345.0
+ CAST(1.2345 AS Uint8), -- 1
+ CAST(12345 AS String), -- "12345"
+ CAST("1.2345" AS Decimal(5, 2)), -- 1.23
+ CAST("xyz" AS Uint64) IS NULL, -- true, because it failed
+ CAST(-1 AS Uint16) IS NULL, -- true, a negative integer cast to an unsigned integer
+ CAST([-1, 0, 1] AS List<Uint8?>), -- [null, 0, 1]
+ --The item type is optional: the failed item is cast to null.
+ CAST(["3.14", "bad", "42"] AS List<Float>), -- [3.14, 42]
+ --The item type is not optional: the failed item has been deleted.
+ CAST(255 AS Uint8), -- 255
+ CAST(256 AS Uint8) IS NULL -- true, out of range
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/_includes/decimal_args.md b/ydb/docs/en/core/yql/reference/yql-core/_includes/decimal_args.md
new file mode 100644
index 00000000000..60b818ec591
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/_includes/decimal_args.md
@@ -0,0 +1,5 @@
+For the Decimal parametric data type, two additional arguments are specified:
+
+* Total number of decimal places (up to 35, inclusive).
+* Number of places after the decimal point (out of the total number, meaning it can't be larger than the previous argument).
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/agg_list.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/agg_list.md
new file mode 100644
index 00000000000..74d3ef437c6
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/agg_list.md
@@ -0,0 +1,39 @@
+## AGGREGATE_LIST {#agg-list}
+
+Get all column values as a list. When combined with `DISTINCT`, it returns only distinct values. The optional second parameter sets the maximum number of values to be returned.
+
+If you know already that you have few distinct values, use the `AGGREGATE_LIST_DISTINCT` aggregate function to build the same result in memory (that might not be enough for a large number of distinct values).
+
+The order of elements in the result list depends on the implementation and can't be set externally. To return an ordered list, sort the result, for example, with [ListSort](../../list.md#listsort).
+
+To return a list of multiple values from one line, *DO NOT* use the `AGGREGATE_LIST` function several times, but add all the needed values to a container, for example, via [AsList](../../basic.md#aslist) or [AsTuple](../../basic.md#astuple), then pass this container to a single `AGGREGATE_LIST` call.
+
+For example, you can combine it with `DISTINCT` and the function [String::JoinFromList](../../../udf/list/string.md) (it's an equivalent of `','.join(list)` in Python) to output to a string all the values found in the column after [GROUP BY](../../../syntax/group_by.md).
+
+**Examples**
+
+```yql
+SELECT
+ AGGREGATE_LIST( region ),
+ AGGREGATE_LIST( region, 5 ),
+ AGGREGATE_LIST( DISTINCT region ),
+ AGGREGATE_LIST_DISTINCT( region ),
+ AGGREGATE_LIST_DISTINCT( region, 5 )
+FROM users
+```
+
+```yql
+-- An equivalent of GROUP_CONCAT in MySQL
+SELECT
+ String::JoinFromList(CAST(AGGREGATE_LIST(region, 2) AS List<String>), ",")
+FROM users
+```
+
+These functions also have a short notation: `AGG_LIST` and `AGG_LIST_DISTINCT`.
+
+{% note alert %}
+
+Execution is **NOT** lazy, so when you use it, be sure that the list has a reasonable size (about a thousand items or less). To stay on the safe side, better use a second optional numeric argument that limits the number of items in the list.
+
+{% endnote %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/aggregate_by.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/aggregate_by.md
new file mode 100644
index 00000000000..92a7b1bdd61
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/aggregate_by.md
@@ -0,0 +1,25 @@
+## AGGREGATE_BY and MULTI_AGGREGATE_BY {#aggregate-by}
+
+Applying an [aggregation factory](../../basic.md#aggregationfactory) to all values of a column or expression. The `MULTI_AGGREGATE_BY` function requires that the value of a column or expression has a structure, tuple, or list, and applies the factory to each individual element, placing the result in a container of the same format. If different values of a column or expression contain lists of different length, the resulting list will have the smallest of the source lengths.
+
+1. Column, `DISTINCT` column or expression.
+2. Factory.
+
+**Examples:**
+
+```yql
+$count_factory = AggregationFactory("COUNT");
+
+SELECT
+ AGGREGATE_BY(DISTINCT column, $count_factory) as uniq_count
+FROM my_table;
+
+SELECT
+ MULTI_AGGREGATE_BY(nums, AggregationFactory("count")) as count,
+ MULTI_AGGREGATE_BY(nums, AggregationFactory("min")) as min,
+ MULTI_AGGREGATE_BY(nums, AggregationFactory("max")) as max,
+ MULTI_AGGREGATE_BY(nums, AggregationFactory("avg")) as avg,
+ MULTI_AGGREGATE_BY(nums, AggregationFactory("percentile", 0.9)) as p90
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/bool_bit.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/bool_bit.md
new file mode 100644
index 00000000000..fa39add15bb
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/bool_bit.md
@@ -0,0 +1,28 @@
+## BOOL_AND, BOOL_OR and BOOL_XOR {#bool-and-or-xor}
+
+Apply the relevant logical operation (`AND`/`OR`/`XOR`) to all values in a Boolean column or expression.
+
+These functions **don't skip** `NULL` during aggregation, with even one `NULL` turning the result into `NULL`. To skip `NULLs` during aggregation, you can use the functions `MIN`/`MAX` or `BIT_AND`/`BIT_OR`/`BIT_XOR`.
+
+**Examples**
+
+```yql
+SELECT
+ BOOL_AND(bool_column),
+ BOOL_OR(bool_column),
+ BOOL_XOR(bool_column)
+FROM my_table;
+```
+
+## BIT_AND, BIT_OR and BIT_XOR {#bit-and-or-xor}
+
+Apply the relevant bitwise operation to all values of a numeric column or expression.
+
+**Examples**
+
+```yql
+SELECT
+ BIT_XOR(unsigned_numeric_value)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/corr_covar.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/corr_covar.md
new file mode 100644
index 00000000000..8ec9aa6ffb6
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/corr_covar.md
@@ -0,0 +1,27 @@
+## CORRELATION and COVARIANCE {#correlation-covariance}
+
+Correlation and covariance between two columns.
+
+Abbreviated versions are also available: `CORR` or `COVAR`. For covariance, there are also versions with the `SAMPLE`/`POPULATION` suffix that are similar to [VARIANCE](#variance) above.
+
+Unlike most other aggregate functions, they don't skip `NULL`, but accept it as 0.
+
+When you use [aggregation factories](../../basic.md#aggregationfactory), a `Tuple` containing two values is passed as the first [AGGREGATE_BY](#aggregateby) argument.
+
+**Examples**
+
+```yql
+SELECT
+ CORRELATION(numeric_column, another_numeric_column),
+ COVARIANCE(numeric_column, another_numeric_column)
+FROM my_table;
+```
+
+```yql
+$corr_factory = AggregationFactory("CORRELATION");
+
+SELECT
+ AGGREGATE_BY(AsTuple(numeric_column, another_numeric_column), $corr_factory)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/count_distinct_estimate.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/count_distinct_estimate.md
new file mode 100644
index 00000000000..91a9ed20a13
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/count_distinct_estimate.md
@@ -0,0 +1,27 @@
+## CountDistinctEstimate, HyperLogLog, and HLL {#countdistinctestimate}
+
+Approximating the number of unique values using the [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog) algorithm. Logically, it does the same thing as [COUNT(DISTINCT ...)](#count), but runs much faster at the cost of some error.
+
+Arguments:
+
+1. Estimated value
+2. Accuracy (4 to 18 inclusive, 14 by default).
+
+By selecting accuracy, you can trade added resource and RAM consumption for decreased error.
+
+All the three functions are aliases at the moment, but `CountDistinctEstimate` may start using a different algorithm in the future.
+
+**Examples**
+
+```yql
+SELECT
+ CountDistinctEstimate(my_column)
+FROM my_table;
+```
+
+```yql
+SELECT
+ HyperLogLog(my_column, 4)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/histogram.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/histogram.md
new file mode 100644
index 00000000000..4b3dea633c7
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/histogram.md
@@ -0,0 +1,120 @@
+## HISTOGRAM {#histogram}
+
+Plotting an approximate histogram based on a numeric expression with automatic selection of buckets.
+
+[Auxiliary functions](../../../udf/list/histogram.md)
+
+### Basic settings
+
+You can limit the number of buckets using an optional argument. The default value is 100. Keep in mind that added accuracy costs you more computing resources and may negatively affect the query execution time. In extreme cases, it may affect your query success.
+
+### Support for weights
+
+You can specify a "weight" for each value used in the histogram. To do this, pass to the aggregate function the second argument with an expression for calculating the weight. The weight of `1.0` is always used by default. If you use non-standard weights, you may also use the third argument to limit the number of buckets.
+
+If you pass two arguments, the meaning of the second argument is determined by its type (if it's an integer literal, it limits the number of buckets, otherwise it's used as a weight).
+
+{% if tech %}
+
+### Algorithms
+
+* [Source whitepaper](http://jmlr.org/papers/volume11/ben-haim10a/ben-haim10a.pdf);
+
+Various modifications of the algorithm are available:
+
+```yql
+AdaptiveDistanceHistogram
+AdaptiveWeightHistogram
+AdaptiveWardHistogram
+BlockWeightHistogram
+BlockWardHistogram
+```
+
+By default, `HISTOGRAM` is a synonym for `AdaptiveWardHistogram`. Both functions are equivalent and interchangeable in all contexts.
+
+The Distance, Weight, and Ward algorithms differ in the formulas that combine two points into one:
+
+```c++
+ TWeightedValue CalcDistanceQuality(const TWeightedValue& left, const TWeightedValue& right) {
+ return TWeightedValue(right.first - left.first, left.first);
+ }
+
+ TWeightedValue CalcWeightQuality(const TWeightedValue& left, const TWeightedValue& right) {
+ return TWeightedValue(right.second + left.second, left.first);
+ }
+
+ TWeightedValue CalcWardQuality(const TWeightedValue& left, const TWeightedValue& right) {
+ const double N1 = left.second;
+ const double N2 = right.second;
+ const double mu1 = left.first;
+ const double mu2 = right.first;
+ return TWeightedValue(N1 * N2 / (N1 + N2) * (mu1 - mu2) * (mu1 - mu2), left.first);
+ }
+```
+
+Difference between Adaptive and Block:
+
+<blockquote>Contrary to adaptive histogram, block histogram doesn't rebuild bins after each point is added. Instead, it accumulates points and if the amount of points overflows specified limits, it shrinks all the points at once to produce a histogram. Indeed, there exist two limits and two shrinkage operations:
+
+1. FastGreedyShrink is fast but coarse. It is used to shrink from upper limit to intermediate limit (override FastGreedyShrink to set specific behaviour).
+2. SlowShrink is slow, but produces finer histogram. It shrinks from the intermediate limit to the actual number of bins in a manner similar to that in adaptive histogram (set CalcQuality in 34constuctor)
+While FastGreedyShrink is used most of the time, SlowShrink is mostly used for histogram finalization
+
+</blockquote>
+{% endif %}
+
+### If you need an accurate histogram
+
+1. You can use the aggregate functions described below with fixed bucket grids: [LinearHistogram](#linearhistogram) or [LogarithmicHistogram](#logarithmichistogram).
+2. You can calculate the bucket number for each row and apply to it [GROUP BY](../../../syntax/group_by.md).
+
+When you use [aggregation factories](../../basic.md#aggregationfactory), a `Tuple` containing a value and a weight is passed as the first [AGGREGATE_BY](#aggregateby) argument.
+
+**Examples**
+
+```yql
+SELECT
+ HISTOGRAM(numeric_column)
+FROM my_table;
+```
+
+```yql
+SELECT
+ Histogram::Print(
+ HISTOGRAM(numeric_column, 10),
+ 50
+ )
+FROM my_table;
+```
+
+```yql
+$hist_factory = AggregationFactory("HISTOGRAM");
+
+SELECT
+ AGGREGATE_BY(AsTuple(numeric_column, 1.0), $hist_factory)
+FROM my_table;
+```
+
+## LinearHistogram, LogarithmicHistogram, and LogHistogram {#linearhistogram}
+
+Plotting a histogram based on an explicitly specified fixed bucket scale.
+
+Arguments:
+
+1. Expression used to plot the histogram. All the following arguments are optional.
+2. Spacing between the `LinearHistogram` buckets or the logarithm base for `LogarithmicHistogram`/`LogHistogram` (those are aliases). In both cases, the default value is 10.
+3. Minimum value. By default, it's minus infinity.
+4. Maximum value. By default, it's plus infinity.
+
+The format of the result is totally similar to [adaptive histograms](#histogram), so you can use the same [set of auxiliary functions](../../../udf/list/histogram.md).
+
+If the spread of input values is uncontrollably large, we recommend that you specify the minimum and maximum values to prevent potential failures due to high memory consumption.
+
+**Examples**
+
+```yql
+SELECT
+ LogarithmicHistogram(numeric_column, 2)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/max_min_by.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/max_min_by.md
new file mode 100644
index 00000000000..a858dc03b5e
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/max_min_by.md
@@ -0,0 +1,40 @@
+## MAX_BY and MIN_BY {#max-min-by}
+
+Return the value of the first argument for the table row where the second argument is minimum/maximum.
+
+You can optionally specify the third argument N that affects behavior if the table has multiple rows with the same minimum or maximum value:
+
+* If N is omitted, the value of one of the rows is returned, and the other rows are discarded.
+* If N is specified, the list is returned with all values, but their number can't exceed N. All values after the number are discarded.
+
+When choosing N, we recommend that you don't exceed several hundreds or thousands to avoid issues with the limited memory available on {{ backend_name }} clusters.
+
+If your task needs absolutely all values, and their number is measured in dozens of thousands or more, then instead of those aggregate functions better use `JOIN` on the source table with a subquery doing `GROUP BY + MIN/MAX` on the desired columns of this table.
+
+{% note warning "Attention" %}
+
+If the second argument is always NULL, the aggregation result is NULL.
+
+{% endnote %}
+
+When you use [aggregation factories](../../basic.md#aggregationfactory), a `Tuple` containing a value and a key is passed as the first [AGGREGATE_BY](#aggregateby) argument.
+
+**Examples**
+
+```yql
+SELECT
+ MIN_BY(value, LENGTH(value)),
+ MAX_BY(value, key, 100)
+FROM my_table;
+```
+
+```yql
+$min_by_factory = AggregationFactory("MIN_BY");
+$max_by_factory = AggregationFactory("MAX_BY", 100);
+
+SELECT
+ AGGREGATE_BY(AsTuple(value, LENGTH(value)), $min_by_factory),
+ AGGREGATE_BY(AsTuple(value, key), $max_by_factory)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/percentile_median.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/percentile_median.md
new file mode 100644
index 00000000000..5bac2b8f608
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/percentile_median.md
@@ -0,0 +1,17 @@
+## PERCENTILE and MEDIAN {#percentile-median}
+
+Calculating percentiles using the amortized version of the [TDigest](https://github.com/tdunning/t-digest) algorithm. `MEDIAN`: An alias for `PERCENTILE(N, 0.5)`.
+
+{% note info "Restriction" %}
+
+The first argument (N) must be a table column name. If you need to bypass this restriction, use a subquery. The restriction is introduced to simplify calculations, since the implementation merges the calls with the same first argument (N) into a single pass.
+
+{% endnote %}
+
+```yql
+SELECT
+ MEDIAN(numeric_column),
+ PERCENTILE(numeric_column, 0.99)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/session_start.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/session_start.md
new file mode 100644
index 00000000000..62e1db4f2a0
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/session_start.md
@@ -0,0 +1,6 @@
+## SessionStart {#session-start}
+
+No arguments. It's allowed only if there is [SessionWindow](../../../syntax/group_by.md#session-window) in [GROUP BY](../../../syntax/group_by.md) / [PARTITION BY](../../../syntax/window.md#partition).
+Returns the value of the `SessionWindow` key column. If `SessionWindow` has two arguments, it returns the minimum value of the first argument within the group/section.
+In the case of the expanded version `SessionWindow`, it returns the value of the second element from the tuple returned by `<calculate_lambda>`, for which the first tuple element is `True`.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/simple.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/simple.md
new file mode 100644
index 00000000000..12fe0a0af37
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/simple.md
@@ -0,0 +1,134 @@
+## COUNT {#count}
+
+Counting the number of rows in the table (if `*` or constant is specified as the argument) or non-empty values in a table column (if the column name is specified as an argument).
+
+Like other aggregate functions, it can be combined with [GROUP BY](../../../syntax/group_by.md) to get statistics on the parts of the table that correspond to the values in the columns being grouped. {% if select_statement != "SELECT STREAM" %}Use the modifier [DISTINCT](../../../syntax/group_by.md#distinct) to count distinct values.{% endif %}
+
+**Examples**
+
+```yql
+SELECT COUNT(*) FROM my_table;
+```
+
+```yql
+SELECT key, COUNT(value) FROM my_table GROUP BY key;
+```
+
+{% if select_statement != "SELECT STREAM" %}
+
+```yql
+SELECT COUNT(DISTINCT value) FROM my_table;
+```
+
+{% endif %}
+
+## MIN and MAX {#min-max}
+
+Minimum or maximum value.
+
+As an argument, you may use an arbitrary computable expression with a numeric result.
+
+**Examples**
+
+```yql
+SELECT MIN(value), MAX(value) FROM my_table;
+```
+
+## SUM {#sum}
+
+Sum of the numbers.
+
+As an argument, you may use an arbitrary computable expression with a numeric result.
+
+Integers are automatically expanded to 64 bits to reduce the risk of overflow.
+
+```yql
+SELECT SUM(value) FROM my_table;
+```
+
+## AVG {#avg}
+
+Arithmetic average.
+
+As an argument, you may use an arbitrary computable expression with a numeric result.
+
+Integer values and time intervals are automatically converted to Double.
+
+**Examples**
+
+```yql
+SELECT AVG(value) FROM my_table;
+```
+
+## COUNT_IF {#count-if}
+
+Number of rows for which the expression specified as the argument is true (the expression's calculation result is true).
+
+The value `NULL` is equated to `false` (if the argument type is `Bool?`).
+
+The function *does not* do the implicit type casting to Boolean for strings and numbers.
+
+**Examples**
+
+```yql
+SELECT
+ COUNT_IF(value % 2 == 1) AS odd_count
+```
+
+{% if select_statement != "SELECT STREAM" %}
+{% note info %}
+
+To count distinct values in rows meeting the condition, unlike other aggregate functions, you can't use the modifier [DISTINCT](../../../syntax/group_by.md#distinct) because arguments contain no values. To get this result, use in the subquery the built-in function [IF](../../../builtins/basic.md#if) with two arguments (to get `NULL` in else), and apply an outer [COUNT(DISTINCT ...)](#count) to its result.
+
+{% endnote %}
+{% endif %}
+
+## SUM_IF and AVG_IF {#sum-if}
+
+Sum or arithmetic average, but only for the rows that satisfy the condition passed by the second argument.
+
+Therefore, `SUM_IF(value, condition)` is a slightly shorter notation for `SUM(IF(condition, value))`, same for `AVG`. The argument's data type expansion is similar to the same-name functions without a suffix.
+
+**Examples**
+
+```yql
+SELECT
+ SUM_IF(value, value % 2 == 1) AS odd_sum,
+ AVG_IF(value, value % 2 == 1) AS odd_avg,
+FROM my_table;
+```
+
+When you use [aggregation factories](../../basic.md#aggregationfactory), a `Tuple` containing a value and a predicate is passed as the first [AGGREGATE_BY](#aggregateby) argument.
+
+**Examples**
+
+```yql
+$sum_if_factory = AggregationFactory("SUM_IF");
+$avg_if_factory = AggregationFactory("AVG_IF");
+
+SELECT
+ AGGREGATE_BY(AsTuple(value, value % 2 == 1), $sum_if_factory) AS odd_sum,
+ AGGREGATE_BY(AsTuple(value, value % 2 == 1), $avg_if_factory) AS odd_avg
+FROM my_table;
+```
+
+## SOME {#some}
+
+Get the value for an expression specified as an argument, for one of the table rows. Gives no guarantee of which row is used. It's similar to the [any()]{% if lang == "en" %}(https://clickhouse.tech/docs/en/sql-reference/aggregate-functions/reference/any/){% else %}(https://clickhouse.tech/docs/ru/sql-reference/aggregate-functions/reference/any/){% endif %} function in ClickHouse.
+
+Because of no guarantee, `SOME` is computationally cheaper than [MIN](#min)/[MAX](#max) often used in similar situations.
+
+**Examples**
+
+```yql
+SELECT
+ SOME(value)
+FROM my_table;
+```
+
+{% note alert %}
+
+When the aggregate function `SOME` is called multiple times, it's **not** guaranteed that all the resulting values are taken from the same row of the source table. To get this guarantee, pack the values into any container and pass it to `SOME`. For example, in the case of a structure, you can apply [AsStruct](../../../builtins/basic.md#asstruct)
+
+{% endnote %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/stddev_variance.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/stddev_variance.md
new file mode 100644
index 00000000000..8b3c239107b
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/stddev_variance.md
@@ -0,0 +1,22 @@
+## STDDEV and VARIANCE {#stddev-variance}
+
+Standard deviation and variance in a column. Those functions use a [single-pass parallel algorithm](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Parallel_algorithm), whose result may differ from the more common methods requiring two passes through the data.
+
+By default, the sample variance and standard deviation are calculated. Several write methods are available:
+
+* with the `POPULATION` suffix/prefix, for example: `VARIANCE_POPULATION`, `POPULATION_VARIANCE` calculates the variance or standard deviation for the population.
+* With the `SAMPLE` suffix/prefix or without a suffix, for example, `VARIANCE_SAMPLE`, `SAMPLE_VARIANCE`, `SAMPLE` calculate sample variance and standard deviation.
+
+Several abbreviated aliases are also defined, for example, `VARPOP` or `STDDEVSAMP`.
+
+If all the values passed are `NULL`, it returns `NULL`.
+
+**Examples**
+
+```yql
+SELECT
+ STDDEV(numeric_column),
+ VARIANCE(numeric_column)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/top_bottom.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/top_bottom.md
new file mode 100644
index 00000000000..8a80dc8ac7d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/top_bottom.md
@@ -0,0 +1,48 @@
+## TOP and BOTTOM {#top-bottom}
+
+Return a list of the maximum/minimum values of an expression. The first argument is an expression, the second argument limits the number of items.
+
+**Examples**
+
+```yql
+SELECT
+ TOP(key, 3),
+ BOTTOM(value, 3)
+FROM my_table;
+```
+
+```yql
+$top_factory = AggregationFactory("TOP", 3);
+$bottom_factory = AggregationFactory("BOTTOM", 3);
+
+SELECT
+ AGGREGATE_BY(key, $top_factory),
+ AGGREGATE_BY(value, $bottom_factory)
+FROM my_table;
+```
+
+## TOP_BY and BOTTOM_BY {#top-bottom-by}
+
+Return a list of values of the first argument for the rows containing the maximum/minimum values of the second argument. The third argument limits the number of items in the list.
+
+When you use [aggregation factories](../../basic.md#aggregationfactory), a `Tuple` containing a value and a key is passed as the first [AGGREGATE_BY](#aggregateby) argument. In this case, the limit for the number of items is passed by the second argument at factory creation.
+
+**Examples**
+
+```yql
+SELECT
+ TOP_BY(value, LENGTH(value), 3),
+ BOTTOM_BY(value, key, 3)
+FROM my_table;
+```
+
+```yql
+$top_by_factory = AggregationFactory("TOP_BY", 3);
+$bottom_by_factory = AggregationFactory("BOTTOM_BY", 3);
+
+SELECT
+ AGGREGATE_BY(AsTuple(value, LENGTH(value)), $top_by_factory),
+ AGGREGATE_BY(AsTuple(value, key), $bottom_by_factory)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/topfreq_mode.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/topfreq_mode.md
new file mode 100644
index 00000000000..9812d98c6c4
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/aggregation/topfreq_mode.md
@@ -0,0 +1,23 @@
+## TOPFREQ and MODE {#topfreq-mode}
+
+Getting an approximate list of the most common values in a column with an estimation of their count. Returns a list of structures with two fields:
+
+* `Value`: the frequently occurring value that was found.
+* `Frequency`: An estimated value occurrence in the table.
+
+Required argument: the value itself.
+
+Optional arguments:
+
+1. For `TOPFREQ`, the desired number of items in the result. `MODE` is an alias to `TOPFREQ` with this argument set to 1. For `TOPFREQ`, this argument is also 1 by default.
+2. The number of items in the buffer used: lets you trade memory consumption for accuracy. Default: 100.
+
+**Examples**
+
+```yql
+SELECT
+ MODE(my_column),
+ TOPFREQ(my_column, 5, 1000)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/abs.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/abs.md
new file mode 100644
index 00000000000..1c563cba956
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/abs.md
@@ -0,0 +1,10 @@
+## Abs {#abs}
+
+The absolute value of the number.
+
+**Examples**
+
+```yql
+SELECT Abs(-123); -- 123
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/aggr_factory.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/aggr_factory.md
new file mode 100644
index 00000000000..0302b69fc38
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/aggr_factory.md
@@ -0,0 +1,77 @@
+## AggregationFactory {#aggregationfactory}
+
+Create a factory for [aggregation functions](../../aggregation.md) to separately describe the methods of aggregation and data types subject to aggregation.
+
+Arguments:
+
+1. A string in double quotes with the name of an aggregate function, for example ["MIN"](../../aggregation.md#min).
+2. Optional parameters of the aggregate function that are data-independent. For example, the percentile value in [PERCENTILE](../../aggregation.md#percentile).
+
+The resulting factory can be used as the second parameter of the function [AGGREGATE_BY](../../aggregation.md#aggregateby).
+If the aggregate function is applied to two columns instead of one, as, for example, [MIN_BY](../../aggregation.md#minby), then in [AGGREGATE_BY](../../aggregation.md#aggregateby), the first argument passes a `Tuple` of two values. See more details in the description of the applicable aggregate function.
+
+**Examples:**
+
+```yql
+$factory = AggregationFactory("MIN");
+SELECT
+ AGGREGATE_BY (value, $factory) AS min_value -- apply the MIN aggregation to the "value" column
+FROM my_table;
+```
+
+## AggregateTransform... {#aggregatetransform}
+
+`AggregateTransformInput()` converts an [aggregation factory](../../aggregation.md), for example, obtained using the [AggregationFactory](#aggregationfactory) function, to other factory, in which the specified transformation of input items is performed before starting aggregation.
+
+Arguments:
+
+1. Aggregation factory.
+2. A lambda function with one argument that converts an input item.
+
+**Examples:**
+
+```yql
+$f = AggregationFactory("sum");
+$g = AggregateTransformInput($f, ($x) -> (cast($x as Int32)));
+$h = AggregateTransformInput($f, ($x) -> ($x * 2));
+select ListAggregate([1,2,3], $f); -- 6
+select ListAggregate(["1","2","3"], $g); -- 6
+select ListAggregate([1,2,3], $h); -- 12
+```
+
+`AggregateTransformOutput()` converts an [aggregation factory](../../aggregation.md), for example, obtained using the [AggregationFactory](#aggregationfactory) function, to other factory, in which the specified transformation of the result is performed after ending aggregation.
+
+Arguments:
+
+1. Aggregation factory.
+2. A lambda function with one argument that converts the result.
+
+**Examples:**
+
+```yql
+$f = AggregationFactory("sum");
+$g = AggregateTransformOutput($f, ($x) -> ($x * 2));
+select ListAggregate([1,2,3], $f); -- 6
+select ListAggregate([1,2,3], $g); -- 12
+```
+
+## AggregateFlatten {#aggregateflatten}
+
+Adapts a factory for [aggregation functions](../../aggregation.md), for example, obtained using the [AggregationFactory](#aggregationfactory) function in a way that allows aggregation of list input items. This operation is similar to [FLATTEN LIST BY](../../../syntax/flatten.md): Each list item is aggregated.
+
+Arguments:
+
+1. Aggregation factory.
+
+**Examples:**
+
+```yql
+$i = AggregationFactory("AGGREGATE_LIST_DISTINCT");
+$j = AggregateFlatten($i);
+select AggregateBy(x, $j) from (
+ select [1,2] as x
+ union all
+ select [2,3] as x
+); -- [1, 2, 3]
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/as_container.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/as_container.md
new file mode 100644
index 00000000000..15adedeedae
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/as_container.md
@@ -0,0 +1,38 @@
+## AsTuple, AsStruct, AsList, AsDict, AsSet, AsListStrict, AsDictStrict and AsSetStrict {#as-container}
+
+Creates containers of the applicable types. For container literals, [operator notation](#containerliteral) is also supported.
+
+Specifics:
+
+* The container elements are passed in arguments. Hence, the number of elements in the resulting container is equal to the number of arguments passed, except when the dictionary keys repeat.
+* `AsTuple` and `AsStruct` can be called without arguments, and also the arguments can have different types.
+* The field names in `AsStruct` are set using `AsStruct(field_value AS field_name)`.
+* Creating a list requires at least one argument if you need to output the element types. To create an empty list with the given type of elements, use the function [ListCreate](../../list.md#listcreate). You can create an empty list as an `AsList()` call without arguments. In this case, this expression will have the `EmptyList` type.
+* Creating a dictionary requires at least one argument if you need to output the element types. To create an empty dictionary with the given type of elements, use the function [DictCreate](../../dict.md#dictcreate). You can create an empty dictionary as an `AsDict()` call without arguments, in this case, this expression will have the `EmptyDict` type.
+* Creating a set requires at least one argument if you need to output element types. To create an empty set with the given type of elements, use the function [SetCreate](../../dict.md#setcreate). You can create an empty set as an `AsSet()` call without arguments, in this case, this expression will have the `EmptySet` type.
+* `AsList` outputs the common type of elements in the list. A type error is raised in the case of incompatible types.
+* `AsDict` separately outputs the common types for keys and values. A type error is raised in the case of incompatible types.
+* `AsSet` outputs common types for keys. A type error is raised in the case of incompatible types.
+* `AsListStrict`, `AsDictStrict`, `AsSetStrict` require the same type for their arguments.
+* `AsDict` and `AsDictStrict` expect `Tuple` of two elements as arguments (key and value, respectively). If the keys repeat, only the value for the first key remains in the dictionary.
+* `AsSet` and `AsSetStrict` expect keys as arguments.
+
+**Examples**
+
+```yql
+SELECT
+ AsTuple(1, 2, "3") AS `tuple`,
+ AsStruct(
+ 1 AS a,
+ 2 AS b,
+ "3" AS c
+ ) AS `struct`,
+ AsList(1, 2, 3) AS `list`,
+ AsDict(
+ AsTuple("a", 1),
+ AsTuple("b", 2),
+ AsTuple("c", 3)
+ ) AS `dict`,
+ AsSet(1, 2, 3) AS `set`
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/as_tagged.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/as_tagged.md
new file mode 100644
index 00000000000..326cdb98120
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/as_tagged.md
@@ -0,0 +1,17 @@
+## AsTagged, Untag {#as-tagged}
+
+Wraps the value in the [Tagged data type](../../../types/special.md) with the specified tag, preserving the physical data type. `Untag`: The reverse operation.
+
+Required arguments:
+
+1. Value of any type.
+2. Tag name.
+
+Returns a copy of the value from the first argument with the specified tag in the data type.
+
+Examples of use cases:
+
+* Returns to the client's web interface the media files from BASE64-encoded strings{% if feature_webui %}. Tag support in the YQL Web UI [is described here](../../../interfaces/web_tagged.md){% endif %}.
+{% if feature_mapreduce %}* Prevent passing of invalid values at the boundaries of UDF calls.{% endif %}
+* Additional refinements at the level of returned columns types.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/bitops.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/bitops.md
new file mode 100644
index 00000000000..2ecf0818d4b
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/bitops.md
@@ -0,0 +1,19 @@
+## ...Bit {#bitops}
+
+`TestBit()`, `ClearBit()`, `SetBit()` and `FlipBit()`: Test, clear, set, or flip a bit in an unsigned number using the specified bit sequence number.
+
+Arguments:
+
+1. An unsigned number that's subject to the operation. TestBit is also implemented for strings.
+2. Number of the bit.
+
+TestBit returns `true/false`. The other functions return a copy of their first argument with the corresponding conversion.
+
+**Examples:**
+
+```yql
+SELECT
+ TestBit(1u, 0), -- true
+ SetBit(8u, 0); -- 9
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/byteat.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/byteat.md
new file mode 100644
index 00000000000..ef9c9d0bde9
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/byteat.md
@@ -0,0 +1,18 @@
+## ByteAt {#byteat}
+
+Getting the byte value inside a string at an index counted from the beginning of the string. If an invalid index is specified, `NULL` is returned.
+
+Arguments:
+
+1. String: `String` or `Utf8`.
+2. Index: `Uint32`.
+
+**Examples**
+
+```yql
+SELECT
+ ByteAt("foo", 0), -- 102
+ ByteAt("foo", 1), -- 111
+ ByteAt("foo", 9); -- NULL
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/callable.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/callable.md
new file mode 100644
index 00000000000..30cd21dffb4
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/callable.md
@@ -0,0 +1,24 @@
+## Callable {#callable}
+
+Create a callable value with the specified signature from a lambda function. It's usually used to put callable values into containers.
+
+Arguments:
+
+1. Type.
+2. Lambda function.
+
+**Examples:**
+
+```yql
+$lambda = ($x) -> {
+ RETURN CAST($x as String)
+};
+
+$callables = AsTuple(
+ Callable(Callable<(Int32)->String>, $lambda),
+ Callable(Callable<(Bool)->String>, $lambda),
+);
+
+SELECT $callables.0(10), $callables.1(true);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/coalesce.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/coalesce.md
new file mode 100644
index 00000000000..09fe299a602
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/coalesce.md
@@ -0,0 +1,32 @@
+## COALESCE {#coalesce}
+
+Iterates through the arguments from left to right and returns the first non-empty argument found. To be sure that the result is non-empty (not of an [optional type](../../../types/optional.md)), the rightmost argument must be of this type (often a literal is used for this). With a single argument, returns this argument unchanged.
+
+Lets you pass potentially empty values to functions that can't handle them by themselves.
+
+A short format using the low-priority `??` operator is available (lower than the Boolean operations). You can use the `NVL` alias.
+
+**Examples**
+
+```yql
+SELECT COALESCE(
+ maybe_empty_column,
+ "it's empty!"
+) FROM my_table;
+```
+
+```yql
+SELECT
+ maybe_empty_column ?? "it's empty!"
+FROM my_table;
+```
+
+```yql
+SELECT NVL(
+ maybe_empty_column,
+ "it's empty!"
+) FROM my_table;
+```
+
+<span style="color: gray;">(all three examples above are equivalent)</span>
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/container_literal.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/container_literal.md
new file mode 100644
index 00000000000..9ea09391d6e
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/container_literal.md
@@ -0,0 +1,36 @@
+## Container literals {#containerliteral}
+
+Some containers support operator notation for their literal values:
+
+* Tuple: `(value1, value2...)`;
+* Structure: `<|name1: value1, name2: value2...|>`;
+* List: `[value1, value2,...]`;
+* Dictionary: `{key1: value1, key2: value2...}`;
+* Set: `{key1, key2...}`.
+
+In every case, you can use an insignificant trailing comma. For a tuple with one element, this comma is required: ```(value1,)```.
+For field names in the structure literal, you can use an expression that can be calculated at evaluation time, for example, string literals or identifiers (including those enclosed in backticks).
+
+For nested lists, use [AsList](#aslist), for nested dictionaries, use [AsDict](#asdict), for nested sets, use [AsSet](#asset), for nested tuples, use [AsTuple](#astuple), for nested structures, use [AsStruct](#asstruct).
+
+**Examples**
+
+```yql
+$name = "computed " || "member name";
+SELECT
+ (1, 2, "3") AS `tuple`,
+ <|
+ `complex member name`: 2.3,
+ b: 2,
+ $name: "3",
+ "inline " || "computed member name": false
+ |> AS `struct`,
+ [1, 2, 3] AS `list`,
+ {
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ } AS `dict`,
+ {1, 2, 3} AS `set`
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/current_tz.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/current_tz.md
new file mode 100644
index 00000000000..c7748e2ff9a
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/current_tz.md
@@ -0,0 +1,49 @@
+## CurrentTz... {#current-tz}
+
+`CurrentTzDate()`, `CurrentTzDatetime()`, and `CurrentTzTimestamp()`: Get the current date and/or time in the [IANA time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) specified in the first argument. The result data type is specified at the end of the function name.
+
+The arguments that follow are optional and work same as [RANDOM](#random).
+
+**Examples**
+
+```yql
+SELECT CurrentTzDate("Europe/Moscow");
+```
+
+```yql
+SELECT CurrentTzTimestamp("Europe/Moscow", TableRow()) FROM my_table;
+```
+
+## AddTimezone
+
+Adding the time zone information to the date/time in UTC. In the result of `SELECT` or after `CAST`, a `String` will be subject to the time zone rules used to calculate the time offset.
+
+Arguments:
+
+1. Date: the type is `Date``Datetime`/`Timestamp`.
+2. [The IANA name of the time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
+
+Result type: `TzDate`/`TzDatetime`/`TzTimestamp`, depending on the input data type.
+
+**Examples**
+
+```yql
+SELECT AddTimezone(Datetime("2018-02-01T12:00:00Z"), "Europe/Moscow");
+```
+
+## RemoveTimezone
+
+Removing the time zone data and converting the value to date/time in UTC.
+
+Arguments:
+
+1. Date: the type is `TzDate`/`TzDatetime`/`TzTimestamp`.
+
+Result type: `Date`/`Datetime`/`Timestamp`, depending on the input data type.
+
+**Examples**
+
+```yql
+SELECT RemoveTimezone(TzDatetime("2018-02-01T12:00:00,Europe/Moscow"));
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/current_utc.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/current_utc.md
new file mode 100644
index 00000000000..36bb5eeb026
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/current_utc.md
@@ -0,0 +1,16 @@
+## CurrentUtc... {#current-utc}
+
+`CurrentUtcDate()`, `CurrentUtcDatetime()` and `CurrentUtcTimestamp()`: Getting the current date and/or time in UTC. The result data type is specified at the end of the function name.
+
+The arguments are optional and work same as [RANDOM](#random).
+
+**Examples**
+
+```yql
+SELECT CurrentUtcDate();
+```
+
+```yql
+SELECT CurrentUtcTimestamp(TableRow()) FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/data-type-literals.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/data-type-literals.md
new file mode 100644
index 00000000000..1e201128e2a
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/data-type-literals.md
@@ -0,0 +1,51 @@
+## Literals of primitive types {#data-type-literals}
+
+For primitive types, you can create literals based on string literals.
+
+**Syntax**
+
+<Primitive type>(<string>[, <additional attributes>])
+
+Unlike `CAST("myString" AS MyType)`:
+
+* The check for literal's castability to the desired type occurs at validation.
+* The result is non-optional.
+
+For the data types `Date`, `Datetime`, `Timestamp`, and `Interval`, literals are supported only in the format corresponding to [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). `Interval` has the following differences from the standard:
+
+* It supports the negative sign for shifts to the past.
+* Microseconds can be expressed as fractional parts of seconds.
+* You can't use units of measurement exceeding one week.
+* The options with the beginning/end of the interval and with repetitions, are not supported.
+
+For the data types `TzDate`, `TzDatetime`, `TzTimestamp`, literals are also set in the format meeting [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), but instead of the optional Z suffix, they specify the [IANA name of the time zone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), separated by comma (for example, GMT or Europe/Moscow).
+
+{% include [decimal args](../../../_includes/decimal_args.md) %}
+
+**Examples**
+
+```yql
+SELECT
+ Bool("true"),
+ Uint8("0"),
+ Int32("-1"),
+ Uint32("2"),
+ Int64("-3"),
+ Uint64("4"),
+ Float("-5"),
+ Double("6"),
+ Decimal("1.23", 5, 2), -- up to 5 decimal digits, with 2 after the decimal point
+ String("foo"),
+ Utf8("Hello"),
+ Yson("<a=1>[3;%false]"),
+ Json(@@{"a":1,"b":null}@@),
+ Date("2017-11-27"),
+ Datetime("2017-11-27T13:24:00Z"),
+ Timestamp("2017-11-27T13:24:00.123456Z"),
+ Interval("P1DT2H3M4.567890S"),
+ TzDate("2017-11-27,Europe/Moscow"),
+ TzDatetime("2017-11-27T13:24:00,America/Los_Angeles"),
+ TzTimestamp("2017-11-27T13:24:00.123456,GMT"),
+ Uuid("f9d5cc3f-f1dc-4d9c-b97e-766e57ca4ccb");
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/ensure.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/ensure.md
new file mode 100644
index 00000000000..d2509df357e
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/ensure.md
@@ -0,0 +1,44 @@
+## Ensure... {#ensure}
+
+Checking for the user conditions:
+
+* `Ensure()`: Checking whether the predicate is true at query execution.
+* `EnsureType()`: Checking that the expression type exactly matches the specified type.
+* `EnsureConvertibleTo()`: A soft check of the expression type (with the same rules as for implicit type conversion).
+
+If the check fails, the entire query fails.
+
+Arguments:
+
+1. An expression that will result from a function call if the check is successful. It's also checked for the data type in the corresponding functions.
+2. Ensure uses a Boolean predicate that is checked for being `true`. The other functions use the data type that can be obtained using the [relevant functions](../../types.md), or a string literal with a [text description of the type](../../../types/type_string.md).
+3. An optional string with an error comment to be included in the overall error message when the query is complete. The data itself can't be used for type checks, since the data check is performed at query validation (or can be an arbitrary expression in the case of Ensure).
+
+To check the conditions based on the final calculation result, it's convenient to combine Ensure with [DISCARD SELECT](../../../syntax/discard.md).
+
+**Examples**
+
+```yql
+SELECT Ensure(
+ value,
+ value < 100,
+ "value out or range"
+) AS value FROM my_table;
+```
+
+```yql
+SELECT EnsureType(
+ value,
+ TypeOf(other_value),
+ "expected value and other_value to be of same type"
+) AS value FROM my_table;
+```
+
+```yql
+SELECT EnsureConvertibleTo(
+ value,
+ Double?,
+ "expected value to be numeric"
+) AS value FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/enum.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/enum.md
new file mode 100644
index 00000000000..28729c4441a
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/enum.md
@@ -0,0 +1,31 @@
+## Enum, AsEnum {#enum}
+
+`Enum()` creates an enumeration value.
+
+Arguments:
+
+* A string with the field name
+* Enumeration type
+
+**Example**
+
+```yql
+$enum_type = Enum<Foo, Bar>;
+SELECT
+ Enum("Foo", $enum_type) as Enum1Value,
+ Enum("Bar", $enum_type) as Enum2Value;
+```
+
+`AsEnum()` creates a value of [enumeration](../../../types/containers.md) including one element. This value can be implicitly cast to any enumeration containing such a name.
+
+Arguments:
+
+* A string with the name of an enumeration item
+
+**Example**
+
+```yql
+SELECT
+ AsEnum("Foo");
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/evaluate_expr_atom.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/evaluate_expr_atom.md
new file mode 100644
index 00000000000..096709330db
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/evaluate_expr_atom.md
@@ -0,0 +1,28 @@
+## EvaluateExpr, EvaluateAtom {#evaluate_expr_atom}
+
+Evaluate an expression before the start of the main calculation and input its result to the query as a literal (constant). In many contexts, where only a constant would be expected in standard SQL (for example, in table names, in the number of rows in [LIMIT](../../../syntax/select.md#limit), and so on), this functionality is implicitly enabled automatically.
+
+EvaluateExpr can be used where the grammar already expects an expression. For example, you can use it to:
+
+* Round the current time to days, weeks, or months and insert it into the query to ensure correct [query caching](../../../syntax/pragma.md#yt.querycachemode), although usually when [functions are used to get the current time](#currentutcdate), query caching is completely disabled.
+* Run a heavy calculation with a small result once per query instead of once per job.
+
+EvaluateAtom lets you dynamically create an [atom](../../../types/special.md), but since atoms are mainly controlled from a lower [s-expressions](/docs/s_expressions/functions) level, it's generally not recommended to use this function directly.
+
+The only argument for both functions is the expression for calculation and substitution.
+
+Restrictions:
+
+* The expression must not trigger MapReduce operations.
+* This functionality is fully locked in YQL over YDB.
+
+**Examples:**
+
+```yql
+$now = CurrentUtcDate();
+SELECT EvaluateExpr(
+ DateTime::MakeDate(DateTime::StartOfWeek($now)
+ )
+);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/files.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/files.md
new file mode 100644
index 00000000000..16e63c45e04
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/files.md
@@ -0,0 +1,62 @@
+## FileContent and FilePath {#file-content-path}
+
+Both the [console](../../../interfaces/cli.md) and [web](../../../interfaces/web.md) interfaces let you "attach" arbitrary named files to your query. With these functions, you can use the name of the attached file to get its contents or the path in the sandbox, and then use it as you like in the query.
+
+The `FileContent` and `FilePath` argument is a string with an alias.
+
+**Examples**
+
+```yql
+SELECT "Content of "
+ || FilePath("my_file.txt")
+ || ":\n"
+ || FileContent("my_file.txt");
+```
+
+## FolderPath {#folderpath}
+
+Getting the path to the root of a directory with several "attached" files with the common prefix specified.
+
+The argument is a string with a prefix among aliases.
+
+See also [PRAGMA File](../../../syntax/pragma.md#file) and [PRAGMA Folder](../../../syntax/pragma.md#folder).
+
+**Examples**
+
+```yql
+PRAGMA File("foo/1.txt", "http://url/to/somewhere");
+PRAGMA File("foo/2.txt", "http://url/to/somewhere/else");
+PRAGMA File("bar/3.txt", "http://url/to/some/other/place");
+
+SELECT FolderPath("foo"); -- The directory at the return path will
+ -- include the files 1.txt and 2.txt downloaded from the above links
+```
+
+## ParseFile
+
+Get a list of values from the attached text file. It can be combined with [IN](../../../syntax/expressions.md#in), attaching the file by URL <span style="color:gray;">(see the instruction for attaching files in the {% if feature_webui %}[web interface](../../../interfaces/web.md#attach) and the {% endif %} [client](../../../interfaces/cli.md#attach))</span>.
+
+Only one file format is supported: one value per line.{% if feature_udf_noncpp %} For something more sophisticated, for now you have to write a small UDF in [Python](../../../udf/python.md) or [JavaScript](../../../udf/javascript.md). {% endif %}
+
+Two required arguments:
+
+1. List cell type: only strings and numeric types are supported.
+2. The name of the attached file.
+
+{% note info %}
+
+The return value is a lazy list. For repeat use, wrap it in the function [ListCollect](../../list.md#listcollect)
+
+{% endnote %}
+
+**Examples:**
+
+```yql
+SELECT ListLength(ParseFile("String", "my_file.txt"));
+```
+
+```yql
+SELECT * FROM my_table
+WHERE int_column IN ParseFile("Int64", "my_file.txt"));
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/find.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/find.md
new file mode 100644
index 00000000000..80fecee7ab0
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/find.md
@@ -0,0 +1,58 @@
+## FIND {#find}
+
+Finding the position of a substring in a string.
+
+Required arguments:
+
+* Source string;
+* The substring being searched for.
+
+Optional arguments:
+
+* A position in bytes to start the search with (an integer or `NULL` by default that means "from the beginning of the source string").
+
+Returns the first substring position found or `NULL` (meaning that the desired substring hasn't been found starting from the specified position).
+
+**Examples**
+
+```yql
+SELECT FIND("abcdefg_abcdefg", "abc"); -- 0
+```
+
+```yql
+SELECT FIND("abcdefg_abcdefg", "abc", 1); -- 8
+```
+
+```yql
+SELECT FIND("abcdefg_abcdefg", "abc", 9); -- null
+```
+
+## RFIND {#rfind}
+
+Reverse finding the position of a substring in a string, from the end to the beginning.
+
+Required arguments:
+
+* Source string;
+* The substring being searched for.
+
+Optional arguments:
+
+* A position in bytes to start the search with (an integer or `NULL` by default, meaning "from the end of the source string").
+
+Returns the first substring position found or `NULL` (meaning that the desired substring hasn't been found starting from the specified position).
+
+**Examples**
+
+```yql
+SELECT RFIND("abcdefg_abcdefg", "bcd"); -- 9
+```
+
+```yql
+SELECT RFIND("abcdefg_abcdefg", "bcd", 8); -- 1
+```
+
+```yql
+SELECT RFIND("abcdefg_abcdefg", "bcd", 0); -- null
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/if.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/if.md
new file mode 100644
index 00000000000..dcd486afac2
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/if.md
@@ -0,0 +1,17 @@
+## IF {#if}
+
+Checks the condition: `IF(condition_expression, then_expression, else_expression)`.
+
+It's a simplified alternative for [CASE WHEN ... THEN ... ELSE ... END](../../../syntax/expressions.md#case).
+
+You may omit the `else_expression` argument. In this case, if the condition is false (`condition_expression` returned `false`), an empty value is returned with the type corresponding to `then_expression` and allowing for `NULL`. Hence, the result will have an [optional data type](../../../types/optional.md).
+
+**Examples**
+
+```yql
+SELECT
+ IF(foo > 0, bar, baz) AS bar_or_baz,
+ IF(foo > 0, foo) AS only_positive_foo
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/intro.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/intro.md
new file mode 100644
index 00000000000..d8da1aff4f2
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/intro.md
@@ -0,0 +1,4 @@
+# Basic built-in functions
+
+Below are the general-purpose functions. For specialized functions, there are separate articles: [aggregate functions](../../aggregation.md){% if feature_window_functions %}, [window functions](../../window.md){% endif %}, and functions for [lists](../../list.md), [dictionaries](../../dict.md), [structures](../../struct.md), [data types](../../types.md){% if feature_codegen %}, and [code generation](../../codegen.md){% endif %}.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/length.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/length.md
new file mode 100644
index 00000000000..4dc75910f9f
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/length.md
@@ -0,0 +1,20 @@
+## LENGTH {#length}
+
+Returns the length of the string in bytes. This function is also available under the `LEN` name .
+
+**Examples**
+
+```yql
+SELECT LENGTH("foo");
+```
+
+```yql
+SELECT LEN("bar");
+```
+
+{% note info %}
+
+To calculate the length of a string in Unicode characters, you can use the function [Unicode::GetLength](../../../udf/list/unicode.md).<br><br>To get the number of elements in the list, use the function [ListLength](../../list.md#listlength).
+
+{% endnote %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/max_min.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/max_min.md
new file mode 100644
index 00000000000..d4f4afa9165
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/max_min.md
@@ -0,0 +1,14 @@
+## MAX_OF, MIN_OF, GREATEST, and LEAST {#max-min}
+
+Returns the minimum or maximum among N arguments. Those functions let you replace the SQL standard statement `CASE WHEN a < b THEN a ELSE b END` that would be too sophisticated for N more than two.
+
+The argument types must be mutually castable and accept `NULL`.
+
+`GREATEST` is a synonym for `MAX_OF` and `LEAST` is a synonym for `MIN_OF`.
+
+**Examples**
+
+```yql
+SELECT MIN_OF(1, 2, 3);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/metadata.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/metadata.md
new file mode 100644
index 00000000000..610f9bb0f27
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/metadata.md
@@ -0,0 +1,21 @@
+## Access to the metadata of the current operation {#metadata}
+
+When you run YQL operations via the web interface or HTTP API, you get access to the following data:
+
+* `CurrentOperationId()`: The private ID of the operation.
+* `CurrentOperationSharedId()`: The public ID of the operation.
+* `CurrentAuthenticatedUser()`: The username of the current user.
+
+No arguments.
+
+If this data is missing, for example, when you run operations in the embedded mode, the functions return an empty string.
+
+**Examples**
+
+```yql
+SELECT
+ CurrentOperationId(),
+ CurrentOperationSharedId(),
+ CurrentAuthenticatedUser();
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/nanvl.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/nanvl.md
new file mode 100644
index 00000000000..dc9b16d1b3b
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/nanvl.md
@@ -0,0 +1,19 @@
+## NANVL {#nanvl}
+
+Replaces the values of `NaN` (not a number) in expressions like `Float`, `Double`, or [Optional](../../../types/optional.md).
+
+Arguments:
+
+1. The expression where you want to make a replacement.
+2. The value to replace `NaN`.
+
+If one of the arguments is `Double`, the result is`Double`, otherwise, it's `Float`. If one of the arguments is `Optional`, then the result is `Optional`.
+
+**Examples**
+
+```yql
+SELECT
+ NANVL(double_column, 0.0)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/optional_ops.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/optional_ops.md
new file mode 100644
index 00000000000..d0bc08c13e7
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/optional_ops.md
@@ -0,0 +1,43 @@
+## Just, Unwrap, Nothing {#optional-ops}
+
+`Just()`: Change the value's data type to [optional](../../../types/optional.md) from the current data type (i.e.,`T` is converted to `T?`).
+
+The reverse operation is [Unwrap](#unwrap).
+
+**Examples**
+
+```yql
+SELECT
+ Just("my_string"); -- String?
+```
+
+`Unwrap()`: Converting the [optional](../../../types/optional.md) value of the data type to the relevant non-optional type, raising a runtime error if the data is `NULL`. This means that `T?` becomes `T`.
+
+If the value isn't [optional](../../../types/optional.md), then the function returns its first argument unchanged.
+
+Arguments:
+
+1. Value to be converted.
+2. An optional string with a comment for the error text.
+
+Reverse operation is [Just](#just).
+
+**Examples**
+
+```yql
+$value = Just("value");
+
+SELECT Unwrap($value, "Unexpected NULL for $value");
+```
+
+`Nothing()`: Create an empty value for the specified [Optional](../../../types/optional.md) data type.
+
+**Examples**
+
+```yql
+SELECT
+ Nothing(String?); -- an empty (NULL) value with the String? type
+```
+
+[Learn more about ParseType and other functions for data types](../../types.md).
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/pickle.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/pickle.md
new file mode 100644
index 00000000000..1a852f530ab
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/pickle.md
@@ -0,0 +1,19 @@
+## Pickle, Unpickle {#pickle}
+
+`Pickle()` and `StablePickle()` serialize an arbitrary object into a sequence of bytes, if possible. Typical non-serializable objects are Callable and Resource. The serialization format is not versioned and can be used within a single query. For the Dict type, the StablePickle function pre-sorts the keys, and for Pickle, the order of dictionary elements in the serialized representation isn't defined.
+
+`Unpickle()` is the inverse operation (deserialization), where with the first argument being the data type of the result and the second argument is the string with the result of `Pickle()` or `StablePickle()`.
+
+Examples:
+
+```yql
+SELECT *
+FROM my_table
+WHERE Digest::MurMurHash32(
+ Pickle(TableRow())
+ ) %10 ==0; -- actually, it is better to use TABLESAMPLE
+
+$buf = Pickle(123);
+SELECT Unpickle(Int32, $buf);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/random.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/random.md
new file mode 100644
index 00000000000..1722cc6c9c1
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/random.md
@@ -0,0 +1,51 @@
+## Random... {#random}
+
+Generates a pseudorandom number:
+
+* `Random()`: A floating point number (Double) from 0 to 1.
+* `RandomNumber()`: An integer from the complete Uint64 range.
+* `RandomUuid()`: [Uuid version 4](https://tools.ietf.org/html/rfc4122#section-4.4).
+
+No arguments are used for random number generation: they are only needed to control the time of the call. A new random number is returned at each call. Therefore:
+
+* If Random is called again within a **same query** and with a same set of arguments, the same set of random numbers is returned. Keep in mind that we mean the arguments themselves (i.e., the text between parentheses) rather than their values.
+* Calling of Random with the same set of arguments in **different queries** returns different sets of random numbers.
+
+Use cases:
+
+* `SELECT RANDOM(1);`: Get one random value for the entire query and use it multiple times (to get multiple random values, you can pass various constants of any type).
+* `SELECT RANDOM(1) FROM table;`: The same random number for each row in the table.
+* `SELECT RANDOM(1), RANDOM(2) FROM table;`: Two random numbers for each row of the table, all the numbers in each of the columns are the same.
+* `SELECT RANDOM(some_column) FROM table;`: Different random numbers for each row in the table.
+* `SELECT RANDOM(some_column), RANDOM(some_column) FROM table;`: Different random numbers for each row of the table, but two identical numbers within the same row.
+* `SELECT RANDOM(some_column), RANDOM(some_column + 1) FROM table;` or `SELECT RANDOM(some_column), RANDOM(other_column) FROM table;`: Two columns, with different numbers in both.
+
+**Examples**
+
+```yql
+SELECT
+ Random(key) -- [0, 1)
+FROM my_table;
+```
+
+```yql
+SELECT
+ RandomNumber(key) -- [0, Max<Uint64>)
+FROM my_table;
+```
+
+```yql
+SELECT
+ RandomUuid(key) -- Uuid version 4
+FROM my_table;
+```
+
+```yql
+SELECT
+ RANDOM(column) AS rand1,
+ RANDOM(column) AS rand2, -- same as rand1
+ RANDOM(column, 1) AS randAnd1, -- different from rand1/2
+ RANDOM(column, 2) AS randAnd2 -- different from randAnd1
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/s_expressions.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/s_expressions.md
new file mode 100644
index 00000000000..969b4531e6e
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/s_expressions.md
@@ -0,0 +1,6 @@
+## YQL::, s-expressions {#s-expressions}
+
+For the full list of internal YQL functions, see the [documentation for s-expressions](/docs/s_expressions/functions), an alternative low-level YQL syntax. Any of the functions listed there can also be called from the SQL syntax by adding the `YQL::` prefix to its name. However, we don't recommend doing this, because this mechanism is primarily intended to temporarily bypass possible issues and for internal testing purposes.
+
+If the function is available in SQL syntax without the `YQL::` prefix, then its behavior may differ from the same-name function from the s-expressions documentation, if any.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/starts_ends_with.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/starts_ends_with.md
new file mode 100644
index 00000000000..5a0de652b43
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/starts_ends_with.md
@@ -0,0 +1,29 @@
+## StartsWith, EndsWith {#starts_ends_with}
+
+Checking for a prefix or suffix in a string.
+
+Required arguments:
+
+* Source string;
+* The substring being searched for.
+
+The arguments can be of the `String` or `Utf8` type and can be optional.
+
+**Examples**
+
+```yql
+SELECT StartsWith("abc_efg", "abc") AND EndsWith("abc_efg", "efg"); -- true
+```
+
+```yql
+SELECT StartsWith("abc_efg", "efg") OR EndsWith("abc_efg", "abc"); -- false
+```
+
+```yql
+SELECT StartsWith("abcd", NULL); -- null
+```
+
+```yql
+SELECT EndsWith(NULL, Utf8("")); -- null
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/staticmap.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/staticmap.md
new file mode 100644
index 00000000000..6bb7b716eea
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/staticmap.md
@@ -0,0 +1,24 @@
+## StaticMap
+
+Transforms a structure or tuple by applying a lambda function to each item.
+
+Arguments:
+
+* Structure or tuple.
+* Lambda for processing items.
+
+Result: a structure or tuple with the same number and naming of items as in the first argument, and with item data types determined by lambda results.
+
+**Examples:**
+
+```yql
+SELECT *
+FROM (
+ SELECT
+ StaticMap(TableRow(), ($item) -> {
+ return CAST($item AS String);
+ })
+ FROM my_table
+) FLATTEN COLUMNS; -- converting all columns to rows
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/staticzip.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/staticzip.md
new file mode 100644
index 00000000000..3643e19691b
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/staticzip.md
@@ -0,0 +1,16 @@
+## StaticZip
+
+Merges structures or tuples element-by-element. All arguments (one or more) must be either structures with the same set of fields or tuples of the same length.
+The result will be a structure or tuple, respectively.
+Each item of the result is a tuple comprised of items taken from arguments.
+
+**Examples:**
+
+```yql
+$one = <|k1:1, k2:2.0|>;
+$two = <|k1:3.0, k2:4|>;
+
+-- Adding two structures item-by-item
+SELECT StaticMap(StaticZip($one, $two), ($tuple)->($tuple.0 + $tuple.1)) AS sum;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/substring.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/substring.md
new file mode 100644
index 00000000000..78f533ed6fc
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/substring.md
@@ -0,0 +1,30 @@
+## SUBSTRING {#substring}
+
+Returns a substring.
+
+Required arguments:
+
+* Source string;
+* Position: The offset from the beginning of the string in bytes (integer) or `NULL` meaning "from the beginning".
+
+Optional arguments:
+
+* Substring length: The number of bytes starting from the specified position (an integer, or the default `NULL` meaning "up to the end of the source string").
+
+Indexing starts from zero. If the specified position and length are beyond the string, returns an empty string.
+If the input string is optional, the result is also optional.
+
+**Examples**
+
+```yql
+SELECT SUBSTRING("abcdefg", 3, 1); -- d
+```
+
+```yql
+SELECT SUBSTRING("abcdefg", 3); -- defg
+```
+
+```yql
+SELECT SUBSTRING("abcdefg", NULL, 3); -- abc
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/table_path_name_recindex.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/table_path_name_recindex.md
new file mode 100644
index 00000000000..24dbcfe7452
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/table_path_name_recindex.md
@@ -0,0 +1,57 @@
+## TablePath {#tablepath}
+
+Access to the current table name, which might be needed when you use [CONCAT](../../../syntax/select.md#concat), [RANGE](../../../syntax/select.md#range), and other related functions.
+
+No arguments. Returns a string with the full path or an empty string and warning when used in an unsupported context (for example, when working with a subquery or a range of 1000+ tables).
+
+{% note info %}
+
+The [TablePath](#tablepath), [TableName](#tablename), and [TableRecordIndex](#tablerecordindex) functions don't support temporary and anonymous tables (they return an empty string or 0 for [TableRecordIndex](#tablerecordindex)).
+These functions are calculated when [executing](../../../syntax/select.md#selectexec) projections in `SELECT`, and by that time the current table may already be temporary.
+To avoid such a situation, create a subquery for calculating these functions, as shown in the second example below.
+
+{% endnote %}
+
+**Examples**
+
+```yql
+SELECT TablePath() FROM CONCAT(table_a, table_b);
+```
+
+```yql
+SELECT key, tpath_ AS path FROM (SELECT a.*, TablePath() AS tpath_ FROM RANGE(`my_folder`) AS a)
+WHERE key IN $subquery;
+```
+
+## TableName {#tablename}
+
+Get the table name based on the table path. You can obtain the path using the [TablePath](#tablepath) function or as the `Path` column when using the table function [FOLDER](../../../syntax/select.md#folder).
+
+Optional arguments:
+
+* Path to the table, `TablePath()` is used by default (see also its limitations).
+* Specifying the system ("yt") whose rules are used to determine the table name. You need to specify the system only if [USE](../../../syntax/select.md#use) doesn't specify the current cluster.
+
+**Examples**
+
+```yql
+USE hahn;
+SELECT TableName() FROM CONCAT(table_a, table_b);
+```
+
+```yql
+SELECT TableName(Path, "yt") FROM hahn.FOLDER(folder_name);
+```
+
+## TableRecordIndex {#tablerecordindex}
+
+Access to the current sequence number of a row in the physical source table, **starting from 1** (depends on the storage implementation).
+
+No arguments. When used in combination with [CONCAT](../../../syntax/select.md#concat), [RANGE](../../../syntax/select.md#range) and other similar mechanisms, numbering restarts for each input table. If used in an incorrect context, it returns 0.
+
+**Example**
+
+```yql
+SELECT TableRecordIndex() FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/table_row.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/table_row.md
new file mode 100644
index 00000000000..f6cedf2bf82
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/table_row.md
@@ -0,0 +1,10 @@
+## TableRow{% if feature_join %}, JoinTableRow{% endif %} {#tablerow}
+
+Getting the entire table row as a structure. No arguments{% if feature_join %}. `JoinTableRow` in case of `JOIN` always returns a structure with table prefixes{% endif %}.
+
+**Example**
+
+```yql
+SELECT TableRow() FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/to_from_bytes.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/to_from_bytes.md
new file mode 100644
index 00000000000..75105178ebf
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/to_from_bytes.md
@@ -0,0 +1,15 @@
+## ToBytes and FromBytes {#to-from-bytes}
+
+Conversion of [primitive data types](../../../types/primitive.md) to a string with their binary representation and back. Numbers are represented in the [little endian](https://en.wikipedia.org/wiki/Endianness#Little-endian) format.
+
+**Examples**
+
+```yql
+SELECT
+ ToBytes(123), -- "\u0001\u0000\u0000\u0000"
+ FromBytes(
+ "\xd2\x02\x96\x49\x00\x00\x00\x00",
+ Uint64
+ ); -- 1234567890ul
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/variant.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/variant.md
new file mode 100644
index 00000000000..7854ae7db03
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/variant.md
@@ -0,0 +1,34 @@
+## Variant, AsVariant {#variant}
+
+`Variant()` creates a variant value over a tuple or structure.
+
+Arguments:
+
+* Value
+* String with a field name or tuple index
+* Variant type
+
+**Example**
+
+```yql
+$var_type = Variant<foo: Int32, bar: Bool>;
+
+SELECT
+ Variant(6, "foo", $var_type) as Variant1Value,
+ Variant(false, "bar", $var_type) as Variant2Value;
+```
+
+`AsVariant()` creates a value of a [variant over a structure](../../../types/containers.md) including one field. This value can be implicitly converted to any variant over a structure that has a matching data type for this field name and might include more fields with other names.
+
+Arguments:
+
+* Value
+* A string with the field name
+
+**Example**
+
+```yql
+SELECT
+ AsVariant(6, "foo") as VariantValue
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/weakfield.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/weakfield.md
new file mode 100644
index 00000000000..e8a60bd7964
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/basic/weakfield.md
@@ -0,0 +1,17 @@
+## WeakField {#weakfield}
+
+Fetches a table column from a strong schema, if it is in a strong schema, or from the `_other` and `_rest` fields. If the value is missing, it returns `NULL`.
+
+Syntax: `WeakField([<table>.]<field>, <type>[, <default_value>])`.
+
+The default value is used only if the column is missing in the data schema. To use the default value in any case, use [COALESCE](#coalesce).
+
+**Examples:**
+
+```yql
+SELECT
+ WeakField(my_column, String, "no value"),
+ WeakField(my_table.other_column, Int64)
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/codegen.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/codegen.md
new file mode 100644
index 00000000000..a2c02000336
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/codegen.md
@@ -0,0 +1,187 @@
+# Functions for code generation
+
+When running calculations, you can generate the code including [S-expressions](/docs/s_expressions) nodes. This uses a mechanism for packing the code in the [resource](../../types/special.md). After building the code, you can insert it into the main program using the [EvaluateCode](#evaluatecode) function. For debugging purposes, you can convert the code to a string using the [FormatCode](#formatcode) function.
+
+Possible node types in S-expressions that can be used for code generation:
+
+* An atom is an untyped string of zero or more characters.
+* A list is a sequence of zero or more nodes. It corresponds to the `tuple` type in SQL.
+* A call of a built-in function consists of a name expressed by an atom and a sequence of zero or more nodes that are arguments to this function.
+* Lambda function declaration consists of declaring the names of arguments and a node that is the root of the body for this lambda function.
+* The lambda function argument is a node that can only be used inside the body of the lambda function.
+* World is a special node that labels I/O operations.
+
+The S-expressions nodes form a directed graph. Atoms are always leaf nodes, because they cannot contain child nodes.
+
+In the text representation, S-expressions have the following format:
+
+* Atom: ```'"foo"```. The apostrophe character (') denotes quoting of the next line that is usually enclosed in quotation marks.
+* List: ```'("foo" "bar")```. The apostrophe character (') denotes that there will be no function call in parentheses.
+* Calling the built-in function: ```(foo "bar")```. The first item inside the brackets is the mandatory name of the function followed by the function arguments.
+* Declaring a lambda function: ```(lambda '(x y) (+ x y))```. The `lambda` keyword is followed by a list of argument names and then by the body of the lambda function.
+* The lambda function argument is ```x```. Unlike an atom, a string without an apostrophe character (') references a name in the current scope. When declaring a lambda function, the names of arguments are added to the body's visibility scope, and, if needed, the name is hidden from the global scope.
+* The ```world```.
+
+{% note info %}
+
+To learn more about code generation, see a [separate introductory article](../../guides/codegen.md). Below follows a reference on specific functions.
+
+{% endnote %}
+
+## FormatCode
+
+Serializing the code as [S-expressions](/docs/s_expressions). The code must not contain free arguments of functions, hence, to serialize the lambda function code, you must pass it completely, avoiding passing individual expressions that might contain lambda function arguments.
+
+**Examples:**
+
+```yql
+SELECT FormatCode(AtomCode("foo"));
+-- (
+-- (return '"foo")
+-- )
+```
+
+## WorldCode
+
+Build a code node with the `world` type.
+
+**Examples:**
+
+```yql
+SELECT FormatCode(WorldCode());
+-- (
+-- (return world)
+-- )
+```
+
+## AtomCode
+
+Build a code node with the `atom` type from a string passed to the argument.
+
+**Examples:**
+
+```yql
+SELECT FormatCode(AtomCode("foo"));
+-- (
+-- (return '"foo")
+-- )
+```
+
+## ListCode
+
+Build a code node with the `list` type from a set of nodes or lists of code nodes passed to arguments. In this case, lists of arguments are built in as separately listed code nodes.
+
+**Examples:**
+
+```yql
+SELECT FormatCode(ListCode(
+ AtomCode("foo"),
+ AtomCode("bar")));
+-- (
+-- (return '('"foo" '"bar"))
+-- );
+
+SELECT FormatCode(ListCode(AsList(
+ AtomCode("foo"),
+ AtomCode("bar"))));
+-- (
+-- (return '('"foo" '"bar"))
+-- )
+```
+
+## FuncCode
+
+Build a code node with the `built-in function call` from a string with the function name and a set of nodes or lists of code nodes passed to arguments. In this case, lists of arguments are built in as separately listed code nodes.
+
+**Examples:**
+
+```yql
+SELECT FormatCode(FuncCode(
+ "Baz",
+ AtomCode("foo"),
+ AtomCode("bar")));
+-- (
+-- (return (Baz '"foo" '"bar"))
+-- )
+
+SELECT FormatCode(FuncCode(
+ "Baz",
+ AsList(
+ AtomCode("foo"),
+ AtomCode("bar"))));
+-- (
+-- (return (Baz '"foo" '"bar"))
+-- )
+```
+
+## LambdaCode
+
+You can build a code node with the `lambda function declaration` type from:
+
+* [a Lambda function](../../syntax/expressions.md#lambda), if you know the number of arguments in advance. In this case, the nodes of the `argument` type will be passed as arguments to this lambda function.
+* The number of arguments and a [lambda function](../../syntax/expressions.md#lambda) with one argument. In this case, a list of nodes of the `argument`type will be passed as an argument to this lambda function.
+
+**Examples:**
+
+```yql
+SELECT FormatCode(LambdaCode(($x, $y) -> {
+ RETURN FuncCode("+", $x, $y);
+}));
+-- (
+-- (return (lambda '($1 $2) (+ $1 $2)))
+-- )
+
+SELECT FormatCode(LambdaCode(2, ($args) -> {
+ RETURN FuncCode("*", Unwrap($args[0]), Unwrap($args[1]));
+}));
+-- (
+-- (return (lambda '($1 $2) (* $1 $2)))
+-- )
+```
+
+## EvaluateCode
+
+Substituting the code node passed in the argument, into the main program code.
+
+**Examples:**
+
+```yql
+SELECT EvaluateCode(FuncCode("Int32", AtomCode("1"))); -- 1
+
+$lambda = EvaluateCode(LambdaCode(($x, $y) -> {
+ RETURN FuncCode("+", $x, $y);
+}));
+SELECT $lambda(1, 2); -- 3
+```
+
+## ReprCode
+
+Substituting the code node representing the result of evaluating an expression passed in the argument, into the main program.
+
+**Examples:**
+
+```yql
+$add3 = EvaluateCode(LambdaCode(($x) -> {
+ RETURN FuncCode("+", $x, ReprCode(1 + 2));
+}));
+SELECT $add3(1); -- 4
+```
+
+## QuoteCode
+
+Substituting into the main program the code node that represents an expression or a [lambda function](../../syntax/expressions.md#lambda) passed in the argument. If free arguments of lambda functions were found during the substitution, they are calculated and substituted into the code as in the [ReprCode](#reprcode) function.
+
+**Examples:**
+
+```yql
+$lambda = ($x, $y) -> { RETURN $x + $y };
+$makeClosure = ($y) -> {
+ RETURN EvaluateCode(LambdaCode(($x) -> {
+ RETURN FuncCode("Apply", QuoteCode($lambda), $x, ReprCode($y))
+ }))
+};
+
+$closure = $makeClosure(2);
+SELECT $closure(1); -- 3
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/dict.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/dict.md
new file mode 100644
index 00000000000..b2f126ee8b7
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/dict.md
@@ -0,0 +1,304 @@
+# Functions for dictionaries
+
+## DictCreate {#dictcreate}
+
+Construct an empty dictionary. Two arguments are passed: for a key and a value. Each argument specifies a string with the data type declaration or the type itself built by [type functions](../types.md). There are no dictionaries with an unknown key or value type in YQL. As a key, you can set a [primitive data type](../../types/primitive.md), except for `Yson` and `Json` that may be [optional](../../types/optional.md) or a tuple of them of a length of at least two.
+
+[Documentation for the type definition format](../../types/type_string.md).
+
+**Examples**
+
+```yql
+SELECT DictCreate(String, Tuple<String,Double?>);
+```
+
+```yql
+SELECT DictCreate(Tuple<Int32?,String>, OptionalType(DataType("String")));
+```
+
+## SetCreate {#setcreate}
+
+Construct an empty set. An argument is passed: the key type that can be built by [type functions](../types.md). There are no sets with an unknown key type in YQL. As a key, you can set a [primitive data type](../../types/primitive.md), except for `Yson` and `Json` that may be [optional](../../types/optional.md) or a tuple of them of a length of at least two.
+
+[Documentation for the type definition format](../../types/type_string.md).
+
+**Examples**
+
+```yql
+SELECT SetCreate(String);
+```
+
+```yql
+SELECT SetCreate(Tuple<Int32?,String>);
+```
+
+## DictLength {#dictlength}
+
+The count of items in the dictionary.
+
+**Examples**
+
+```yql
+SELECT DictLength(AsDict(AsTuple(1, AsList("foo", "bar"))));
+```
+
+{% if feature_column_container_type %}
+
+```yql
+SELECT DictLength(dict_column) FROM my_table;
+```
+
+{% endif %}
+
+## DictHasItems {#dicthasitems}
+
+Check that the dictionary contains at least one item.
+
+**Examples**
+
+```yql
+SELECT DictHasItems(AsDict(AsTuple(1, AsList("foo", "bar")))) FROM my_table;
+```
+
+{% if feature_column_container_type %}
+
+```yql
+SELECT DictHasItems(dict_column) FROM my_table;
+```
+
+{% endif %}
+
+## DictItems {#dictitems}
+
+Get dictionary contents as a list of tuples including key-value pairs (`List<Tuplekey_type,value_type>`).
+
+**Examples**
+
+```yql
+SELECT DictItems(AsDict(AsTuple(1, AsList("foo", "bar"))));
+-- [ ( 1, [ "foo", "bar" ] ) ]
+```
+
+{% if feature_column_container_type %}
+
+```yql
+SELECT DictItems(dict_column)
+FROM my_table;
+```
+
+{% endif %}
+
+## DictKeys {#dictkeys}
+
+Get a list of dictionary keys.
+
+**Examples**
+
+```yql
+SELECT DictKeys(AsDict(AsTuple(1, AsList("foo", "bar"))));
+-- [ 1 ]
+```
+
+{% if feature_column_container_type %}
+
+```yql
+SELECT DictKeys(dict_column)
+FROM my_table;
+```
+
+{% endif %}
+
+## DictPayloads {#dictpayloads}
+
+Get a list of dictionary values.
+
+**Examples**
+
+```yql
+SELECT DictPayloads(AsDict(AsTuple(1, AsList("foo", "bar"))));
+-- [ [ "foo", "bar" ] ]
+```
+
+{% if feature_column_container_type %}
+
+```yql
+SELECT DictPayloads(dict_column)
+FROM my_table;
+```
+
+{% endif %}
+
+## DictLookup {#dictlookup}
+
+Get a dictionary element by its key.
+
+**Examples**
+
+```yql
+SELECT DictLookup(AsDict(
+ AsTuple(1, AsList("foo", "bar")),
+ AsTuple(2, AsList("bar", "baz"))
+), 1);
+-- [ "foo", "bar" ]
+```
+
+{% if feature_column_container_type %}
+
+```yql
+SELECT DictLookup(dict_column, "foo")
+FROM my_table;
+```
+
+{% endif %}
+
+## DictContains {#dictcontains}
+
+Checking if an element in the dictionary using its key. Returns true or false.
+
+**Examples**
+
+```yql
+SELECT DictContains(AsDict(
+ AsTuple(1, AsList("foo", "bar")),
+ AsTuple(2, AsList("bar", "baz"))
+), 42);
+-- false
+```
+
+{% if feature_column_container_type %}
+
+```yql
+SELECT DictContains(dict_column, "foo")
+FROM my_table;
+```
+
+{% endif %}
+
+## DictAggregate {#dictaggregate}
+
+Apply [aggregation factory](../basic.md#aggregationfactory) to the passed dictionary where each value is a list. The factory is applied separately inside each key.
+If the list is empty, the aggregation result is the same as for an empty table: 0 for the `COUNT` function and `NULL` for other functions.
+If the list under a certain key is empty in the passed dictionary, such a key is removed from the result.
+If the passed dictionary is optional and contains `NULL`, the result is also `NULL`.
+
+Arguments:
+
+1. Dictionary.
+2. [Aggregation factory](../basic.md#aggregationfactory).
+
+**Examples**
+
+```sql
+SELECT DictAggregate(AsDict(
+ AsTuple(1, AsList("foo", "bar")),
+ AsTuple(2, AsList("baz", "qwe"))),
+ AggregationFactory("Max"));
+-- {1 : "foo", 2 : "qwe" }
+```
+
+## SetIsDisjoint {#setisjoint}
+
+Check that the dictionary doesn't intersect by keys with a list or another dictionary.
+
+So there are two options to make a call:
+
+* With the `Dict<K,V1>` and `List<K>` arguments.
+* With the `Dict<K,V1>` and `Dict<K,V2>` arguments.
+
+**Examples**
+
+```sql
+SELECT SetIsDisjoint(ToSet(AsList(1, 2, 3)), AsList(7, 4)); -- true
+SELECT SetIsDisjoint(ToSet(AsList(1, 2, 3)), ToSet(AsList(3, 4))); -- false
+```
+
+## SetIntersection {#setintersection}
+
+Construct intersection between two dictionaries based on keys.
+
+Arguments:
+
+* Two dictionaries: `Dict<K,V1>` and `Dict<K,V2>`.
+* An optional function that combines the values from the source dictionaries to construct the values of the output dictionary. If such a function has the `(K,V1,V2) -> U` type, the result type is `Dict<K,U>`. If the function is not specified, the result type is `Dict<K,Void>`, and the values from the source dictionaries are ignored.
+
+**Examples**
+
+```yql
+SELECT SetIntersection(ToSet(AsList(1, 2, 3)), ToSet(AsList(3, 4))); -- { 3 }
+SELECT SetIntersection(
+ AsDict(AsTuple(1, "foo"), AsTuple(3, "bar")),
+ AsDict(AsTuple(1, "baz"), AsTuple(2, "qwe")),
+ ($k, $a, $b) -> { RETURN AsTuple($a, $b) });
+-- { 1 : ("foo", "baz") }
+```
+
+## SetIncludes {#setincludes}
+
+Checking that the keys of the specified dictionary include all the elements of the list or the keys of the second dictionary.
+
+So there are two options to make a call:
+
+* With the `Dict<K,V1>` and `List<K>` arguments.
+* With the `Dict<K,V1>` and `Dict<K,V2>` arguments.
+
+**Examples**
+
+```yql
+SELECT SetIncludes(ToSet(AsList(1, 2, 3)), AsList(3, 4)); -- false
+SELECT SetIncludes(ToSet(AsList(1, 2, 3)), ToSet(AsList(2, 3))); -- true
+```
+
+## SetUnion {#setunion}
+
+Constructs a union of two dictionaries based on keys.
+
+Arguments:
+
+* Two dictionaries: `Dict<K,V1>` and `Dict<K,V2>`.
+* An optional function that combines the values from the source dictionaries to construct the values of the output dictionary. If such a function has the `(K,V1?,V2?) -> U` type, the result type is `Dict<K,U>`. If the function is not specified, the result type is `Dict<K,Void>`, and the values from the source dictionaries are ignored.
+
+**Examples**
+
+```yql
+SELECT SetUnion(ToSet(AsList(1, 2, 3)), ToSet(AsList(3, 4))); -- { 1, 2, 3, 4 }
+SELECT SetUnion(
+ AsDict(AsTuple(1, "foo"), AsTuple(3, "bar")),
+ AsDict(AsTuple(1, "baz"), AsTuple(2, "qwe")),
+ ($k, $a, $b) -> { RETURN AsTuple($a, $b) });
+-- { 1 : ("foo", "baz"), 2 : (null, "qwe"), 3 : ("bar", null) }
+```
+
+## SetDifference {#setdifference}
+
+Construct a dictionary containing all the keys with their values in the first dictionary with no matching key in the second dictionary.
+
+**Examples**
+
+```yql
+SELECT SetDifference(ToSet(AsList(1, 2, 3)), ToSet(AsList(3, 4))); -- { 1, 2 }
+SELECT SetDifference(
+ AsDict(AsTuple(1, "foo"), AsTuple(2, "bar")),
+ ToSet(AsList(2, 3)));
+-- { 1 : "foo" }
+```
+
+## SetSymmetricDifference {#setsymmetricdifference}
+
+Construct a symmetric difference between two dictionaries based on keys.
+
+Arguments:
+
+* Two dictionaries: `Dict<K,V1>` and `Dict<K,V2>`.
+* An optional function that combines the values from the source dictionaries to construct the values of the output dictionary. If such a function has the `(K,V1?,V2?) -> U` type, the result type is `Dict<K,U>`. If the function is not specified, the result type is `Dict<K,Void>`, and the values from the source dictionaries are ignored.
+
+**Examples**
+
+```yql
+SELECT SetSymmetricDifference(ToSet(AsList(1, 2, 3)), ToSet(AsList(3, 4))); -- { 1, 2, 4 }
+SELECT SetSymmetricDifference(
+ AsDict(AsTuple(1, "foo"), AsTuple(3, "bar")),
+ AsDict(AsTuple(1, "baz"), AsTuple(2, "qwe")),
+ ($k, $a, $b) -> { RETURN AsTuple($a, $b) });
+-- { 2 : (null, "qwe"), 3 : ("bar", null) }
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/index.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/index.md
new file mode 100644
index 00000000000..702cb639fdc
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/index.md
@@ -0,0 +1,17 @@
+# Built-in YQL functions
+
+- [Basic](../basic.md)
+- [Aggregate](../aggregation.md)
+{% if feature_window_functions %}
+- [Window](../window.md)
+{% endif %}
+- [For lists](../list.md)
+- [For dictionaries](../dict.md)
+- [For structures](../struct.md)
+- [For types](../types.md)
+{% if feature_codegen %}
+- [For code generation](../codegen.md)
+{% endif %}
+- [For JSON](../json.md)
+- [C++ libraries](../../udf/list/index.md)
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/json.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/json.md
new file mode 100644
index 00000000000..c7471b324d8
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/json.md
@@ -0,0 +1,1150 @@
+# Functions for JSON
+
+**JSON** is a lightweight [data-interchange format](https://www.json.org). In YQL, it's represented by the `Json` type. Unlike relational tables, JSON can store data with no schema defined. Here is an example of a valid JSON object:
+
+```json
+[
+ {
+ "name": "Jim Holden",
+ "age": 30
+ },
+ {
+ "name": "Naomi Nagata",
+ "age": "twenty years old"
+ }
+]
+```
+
+Despite the fact that the `age` field in the first object is of the `Number` type (`"age": 21`) and in the second object its type is `String` (`"age": "twenty years old"`), this is a fully valid JSON object.
+
+To work with JSON, YQL implements a subset of the [SQL support for JavaScript Object Notation (JSON)](https://www.iso.org/standard/67367.html) standard, which is part of the common ANSI SQL standard.
+
+## JsonPath
+
+Values inside JSON objects are accessed using a query language called JsonPath. All functions for JSON accept a JsonPath query as an argument.
+
+Let's look at an example. Suppose we have a JSON object like:
+
+```json
+{
+ "comments": [
+ {
+ "id": 123,
+ "text": "A whisper will do, if it's all that you can manage."
+ },
+ {
+ "id": 456,
+ "text": "My life has become a single, ongoing revelation that I haven’t been cynical enough."
+ }
+ ]
+}
+```
+
+Then, to get the text of the second comment, we can write the following JsonPath query:
+
+```
+$.comments[1].text
+```
+
+In this query:
+
+1. `$` is a way to access the entire JSON object.
+2. `$.comments` accesses the `comments` key of the JSON object.
+3. `$.comments[1]` accesses the second element of the JSON array (element numbering starts from 0).
+4. `$.comments[1].text` accesses the `text` key of the JSON object.
+5. Query execution result: `"My life has become a single, ongoing revelation that I haven’t been cynical enough."`
+
+### Quick reference
+
+| Operation | Example |
+| --------------------------------------- | ------------------------------------------------- |
+| Retrieving a JSON object key | `$.key` |
+| Retrieving all JSON object keys | `$.*` |
+| Accessing an array element | `$[25]` |
+| Retrieving an array subsegment | `$[2 to 5]` |
+| Accessing the last array element | `$[last]` |
+| Accessing all array elements | `$[*]` |
+| Unary operations | `- 1` |
+| Binary operations | `(12 * 3) % 4 + 8` |
+| Accessing a variable | `$variable` |
+| Logical operations | `(1 > 2) || (3 <= 4) && ("string" == "another")` |
+| Matching a regular expression | `$.name like_regex "^[A-Za-z]+$"` |
+| Checking the string prefix | `$.name starts with "Bobbie"` |
+| Checking if a path exists | `exists ($.profile.name)` |
+| Checking a Boolean expression for null | `($.age > 20) is unknown` |
+| Filtering values | `$.friends ? (@.age >= 18 && @.gender == "male")` |
+| Getting the value type | `$.name.type()` |
+| Getting the array size | `$.friends.size()` |
+| Converting a string to a number | `$.number.double()` |
+| Rounding up a number | `$.number.ceiling()` |
+| Rounding down a number | `$.number.floor()` |
+| Returning the absolute value | `$.number.abs()` |
+| Getting key-value pairs from an object | `$.profile.keyvalue()` |
+
+### Data model
+
+The result of executing all JsonPath expressions is a sequence of JSON values. For example:
+
+- The result of executing the `"Bobbie"` expression is a sequence with the only element `"Bobbie"`. Its length is 1.
+- The result of executing the `$` expression (that takes the entire JSON object) in JSON `[1, 2, 3]` is `[1, 2, 3]`. A sequence of 1 element of the array `[1, 2, 3]`
+- The result of executing the `$[*]` expression (retrieving all array elements) in JSON `[1, 2, 3]` is `1, 2, 3`. A sequence of three items:`1`, `2`, and `3`
+
+If the input sequence consists of multiple values, some operations are performed for each element (for example, accessing a JSON object key). However, other operations require a sequence of one element as input (for example, binary arithmetic operations).
+
+The behavior of a specific operation is described in the corresponding section of the documentation.
+
+### Execution mode
+
+JsonPath supports two execution modes, `lax` and `strict`. Setting the mode is optional. By default, `lax`. The mode is specified at the beginning of a query. For example, `strict $.key`.
+
+The behavior for each mode is described in the corresponding sections with JsonPath operations.
+
+#### Auto unpacking of arrays
+
+When accessing a JSON object key in `lax` mode, arrays are automatically unpacked.
+
+**Example:**
+
+```json
+[
+ {
+ "key": 123
+ },
+ {
+ "key": 456
+ }
+]
+```
+
+The `lax $.key` query is successful and returns `123, 456`. As `$` is an array, it's automatically unpacked and accessing the key of the `$.key` JSON object is executed for each element in the array.
+
+The `strict $.key` query returns an error. In `strict` mode, there is no support for auto unpacking of arrays. Since `$` is an array and not an object, accessing the `$.key` object key is impossible. You can fix this by writing `strict $[*].key`.
+
+Unpacking is only 1 level deep. In the event of nested arrays, only the outermost one is unpacked.
+
+#### Wrapping values in arrays
+
+When accessing an array element in `lax` mode, JSON values are automatically wrapped in an array.
+
+**Example:**
+
+```json
+{
+ "name": "Avasarala"
+}
+```
+
+The `lax $[0].name` query is successful and returns `"Avasarala"`. As `$` isn't an array, it's automatically wrapped in an array of length 1. Accessing the first element `$[0]` returns the source JSON object where the `name` key is taken.
+
+The `strict $[0].name` query returns an error. In `strict` mode, values aren't wrapped in an array automatically. Since `$` is an object and not an array, accessing the `$[0]` element is impossible. You can fix this by writing `strict $.name`.
+
+#### Handling errors
+
+Some errors are converted to an empty result when a query is executed in `lax` mode.
+
+### Literals
+
+Values of some types can be specified in a JsonPath query using literals:
+
+| Type | Example |
+| ------------------ | ---------------- |
+| Numbers | `42`, `-1.23e-5` |
+| Boolean values | `false`, `true` |
+| Null | `Null` |
+| Stings | `"Belt"` |
+
+### Accessing JSON object keys
+
+JsonPath supports accessing JSON object keys, such as `$.session.user.name`.
+
+{% note info %}
+
+Accessing keys without quotes is only supported for keys that start with an English letter or underscore and only contain English letters, underscores, numbers, and a dollar sign. Use quotes for all other keys. For example, `$.profile."this string has spaces"` or `$.user."42 is the answer"`
+
+{% endnote %}
+
+For each value from the input sequence:
+
+1. If the value is an array, it's automatically unpacked in `lax` mode.
+2. If the value isn't a JSON object or if it is and the specified key is missing from this JSON object, a query executed in `strict` mode fails. In `lax` mode, an empty result is returned for this value.
+
+The expression execution result is the concatenation of the results for each value from the input sequence.
+
+**Example:**
+
+```json
+{
+ "name": "Amos",
+ "friends": [
+ {
+ "name": "Jim"
+ },
+ {
+ "name": "Alex"
+ }
+ ]
+}
+```
+
+| | `lax` | `strict` |
+| ---------------- | ---------------- | -------- |
+| `$.name` | `"Amos"` | `"Amos"` |
+| `$.surname` | Empty result | Error |
+| `$.friends.name` | `"Jim", "Alex"` | Error |
+
+### Accessing all JSON object keys
+
+JsonPath supports accessing all JSON object keys at once: `$.*`.
+
+For each value from the input sequence:
+
+1. If the value is an array, it's automatically unpacked in `lax` mode.
+2. If the value isn't a JSON object, a query executed in `strict` mode fails. In `lax` mode, an empty result is returned for this value.
+
+The expression execution result is the concatenation of the results for each value from the input sequence.
+
+**Example:**
+
+```json
+{
+ "profile": {
+ "id": 123,
+ "name": "Amos"
+ },
+ "friends": [
+ {
+ "name": "Jim"
+ },
+ {
+ "name": "Alex"
+ }
+ ]
+}
+```
+
+| | `lax` | `strict` |
+| ------------- | --------------- | ------------- |
+| `$.profile.*` | `123, "Amos"` | `123, "Amos"` |
+| `$.friends.*` | `"Jim", "Alex"` | Error |
+
+### Accessing an array element
+
+JsonPath supports accessing array elements: `$.friends[1, 3 to last - 1]`.
+
+For each value from the input sequence:
+
+1. If the value isn't an array, a query executed in `strict` mode fails. In `lax` mode, values are automatically wrapped in an array.
+2. The `last` keyword is replaced with the array's last index. Using `last` outside of accessing the array is an error in both modes.
+3. The specified indexes are calculated. Each of them must be a single number, otherwise the query fails in both modes.
+4. If the index is a fractional number, it's rounded down.
+5. If the index goes beyond the array boundaries, the query executed in `strict` mode fails. In `lax` mode, this index is ignored.
+6. If a segment is specified and its start index is greater than the end index (for example, `$[20 to 1]`), the query fails in `strict` mode. In `lax` mode, this segment is ignored.
+7. All elements by the specified indexes are added to the result. Segments include **both ends**.
+
+**Examples**:
+
+```json
+[
+ {
+ "name": "Camina",
+ "surname": "Drummer"
+ },
+ {
+ "name": "Josephus",
+ "surname": "Miller"
+ },
+ {
+ "name": "Bobbie",
+ "surname": "Draper"
+ },
+ {
+ "name": "Julie",
+ "surname": "Mao"
+ }
+]
+```
+
+| | `lax` | `strict` |
+| ----------------------------- | ------------------------------- | ------------------------------- |
+| `$[0].name` | `"Camina"` | `"Camina"` |
+| `$[1, 2 to 3].name` | `"Josephus", "Bobbie", "Julie"` | `"Josephus", "Bobbie", "Julie"` |
+| `$[last - 2].name` | `"Josephus"` | `"Josephus"` |
+| `$[2, last + 200 to 50].name` | `"Bobbie"` | Error |
+| `$[50].name` | Empty result | Error |
+
+### Accessing all array elements
+
+JsonPath supports accessing all array elements at once: `$[*]`.
+
+For each value from the input sequence:
+
+1. If the value isn't an array, a query executed in `strict` mode fails. In `lax` mode, values are automatically wrapped in an array.
+2. All elements of the current array are added to the result.
+
+**Examples:**
+
+```json
+[
+ {
+ "class": "Station",
+ "title": "Medina"
+ },
+ {
+ "class": "Corvette",
+ "title": "Rocinante"
+ }
+]
+```
+
+| | `lax` | `strict` |
+| ------------------- | ------------------------- | ----------------------- |
+| `$[*].title` | `"Medina", "Rocinante"` | `"Medina", "Rocinante"` |
+| `lax $[0][*].class` | `"Station"` | Error |
+
+Let's analyze the last example step by step:
+
+1. `$[0]` returns the first element of the array, that is `{"class": "Station", "title": "Medina"}`
+2. `$[0][*]` expects an array for input, but an object was input instead. It's automatically wrapped in an array as `[ {"class": "Station", "title": "Medina"} ]`
+3. Now, `$[0][*]` can be executed and returns all elements of the array, that is `{"class": "Station", "title": "Medina"}`
+4. `$[0][*].class` returns the `class` field value: `"Station"`.
+
+### Arithmetic operations
+
+{% note info %}
+
+All arithmetic operations work with numbers as with Double. Calculations are made with potential [loss of accuracy](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).
+
+{% endnote %}
+
+#### Unary operations
+
+JsonPath supports unary `+` and `-`.
+
+A unary operation applies to all values from the input sequence. If a unary operation's input is a value that isn't a number, a query fails in both modes.
+
+**Example:**
+
+```json
+[1, 2, 3, 4]
+```
+
+The `strict -$[*]` query is successful and returns `-1, -2, -3, -4`.
+
+The `lax -$` query fails as `$` is an array and not a number.
+
+#### Binary operations
+
+JsonPath supports binary arithmetic operations (in descending order of priority):
+
+1. Multiplication `*`, dividing floating-point numbers `/`, and taking the remainder `%` (works as the `MOD` function in `SQL`).
+2. Addition `+`, subtraction `-`.
+
+You can change the order of operations using parentheses.
+
+If each argument of a binary operation is not a single number or a number is divided by 0, the query fails in both modes.
+
+**Examples:**
+
+- `(1 + 2) * 3` returns `9`
+- `1 / 2` returns `0.5`
+- `5 % 2` returns `1`
+- `1 / 0` fails
+- If JSON is `[-32.4, 5.2]`, the `$[0] % $[1]` query returns `-1.2`
+- If JSON is `[1, 2, 3, 4]`, the `lax $[*] + $[*]` query fails as the `$[*]` expression execution result is `1, 2, 3, 4`, that is multiple numbers. A binary operation only requires one number for each of its arguments.
+
+### Boolean values
+
+Unlike some other programming languages, Boolean values in JsonPath are not only `true` and `false`, but also `null` (uncertainty).
+
+JsonPath considers any values received from a JSON document to be non-Boolean. For example, a query like `! $.is_valid_user` (a logical negation applied to the `is_valid_user`) field is syntactically invalid because the `is_valid_user` field value is not Boolean (even when it actually stores `true` or `false`). The correct way to write this kind of query is to explicitly use a comparison with a Boolean value, such as `$.is_valid_user == false`.
+
+### Logical operations
+
+JsonPath supports some logical operations for Boolean values.
+
+The arguments of any logical operation must be a single Boolean value.
+All logical operations return a Boolean value.
+
+**Logical negation,`!`**
+
+Truth table:
+
+| `x` | `!x` |
+| ------- | ------- |
+| `true` | `false` |
+| `false` | `true` |
+| `Null` | `Null` |
+
+**Logical AND, `&&`**
+
+In the truth table, the first column is the left argument, the first row is the right argument, and each cell is the result of using the Logical AND both with the left and right arguments:
+
+| `&&` | `true` | `false` | `Null` |
+| ------- | ------- | ------- | ------- |
+| `true` | `true` | `false` | `Null` |
+| `false` | `false` | `false` | `false` |
+| `Null` | `Null` | `false` | `Null` |
+
+**Logical OR, `||`**
+
+In the truth table, the first column is the left argument, the first row is the right argument, and each cell is the result of using the logical OR with both the left and right arguments:
+
+| `||` | `true` | `false` | `Null` |
+| ------- | ------- | ------- | ------- |
+| `true` | `true` | `true` | `true` |
+| `false` | `true` | `false` | `Null` |
+| `Null` | `true` | `Null` | `Null` |
+
+**Examples:**
+
+- `! (true == true)`, the result is `false`
+- `(true == true) && (true == false)`, the result is `false`
+- `(true == true) || (true == false)`, the result is `true`
+
+### Comparison operators
+
+JsonPath implements comparison operators for values:
+
+- Equality, `==`
+- Inequality, `!=`and `<>`
+- Less than and less than or equal to, `<` and `=`
+- Greater than and greater than or equal to, `>` and `>=`
+
+All comparison operators return a Boolean value. Both operator arguments support multiple values.
+
+If an error occurs when calculating the operator arguments, it returns `null`. In this case, the JsonPath query execution continues.
+
+The arrays of each of the arguments are automatically unpacked. After that, for each pair where the first element is taken from the sequence of the left argument and the second one from the sequence of the right argument:
+
+1. The elements of the pair are compared
+2. If an error occurs during the comparison, the `ERROR` flag is set.
+3. If the comparison result is true, the flag set is `FOUND`
+4. If either the `ERROR` or `FOUND` flag is set and the query is executed in `lax` mode, no more pairs are analyzed.
+
+If the pair analysis results in:
+
+1. The `ERROR` flag is set, the operator returns `null`
+2. The `FOUND` flag is set, the operator returns `true`
+3. Otherwise, it returns `false`
+
+We can say that this algorithm considers all pairs from the Cartesian product of the left and right arguments, trying to find the pair whose comparison returns true.
+
+Elements in a pair are compared according to the following rules:
+
+1. If the left or right argument is an array or object, the comparison fails.
+2. `null == null` returns true
+3. In all other cases, if one of the arguments is `null`, false is returned.
+4. If the left and right arguments are of different types, the comparison fails.
+5. Strings are compared byte by byte.
+6. `true` is considered greater than `false`
+7. Numbers are compared with the accuracy of `1e-20`
+
+**Example:**
+
+Let's take a JSON document as an example
+
+```json
+{
+ "left": [1, 2],
+ "right": [4, "Inaros"]
+}
+```
+
+and analyze the steps for executing the `lax $.left < $.right` query:
+
+1. Auto unpacking of arrays in the left and right arguments. As a result, the left argument is the sequence `1, 2` and the right argument is `4, "Iranos"`
+2. Let's take the pair `(1, 4)`. The comparison is successful as `1 < 4` is true. Set the flag `FOUND`
+3. Since the query is executed in `lax` mode and the `FOUND` flag is set, we aren't analyzing any more pairs.
+4. Since we have the `FOUND` flag set, the operator returns true.
+
+Let's take the same query in a different execution mode: `strict $.left < $.right`:
+
+1. Auto unpacking of arrays in the left and right arguments. As a result, the left argument is the sequence `1, 2` and the right argument is `4, "Iranos"`
+2. Let's take the pair `(1, 4)`. The comparison is successful as `1 < 4` is true. Set the flag `FOUND`
+3. Let's take the pair `(2, 4)`. The comparison is successful as `2 < 4` is true. Set the flag `FOUND`
+4. Let's take the pair `(1, "Iranos")`. The comparison fails as a number can't be compared with a string. Set the flag `ERROR`
+5. Let's take the pair `(2, "Iranos")`. The comparison fails as a number can't be compared with a string. Set the flag `ERROR`
+6. Since we have the `ERROR` flag set, the operator returns `null`
+
+### Predicates
+
+JsonPath supports predicates which are expressions that return a Boolean value and check a certain condition. You can use them, for example, in filters.
+
+#### `like_regex`
+
+The `like_regex` predicate lets you check if a string matches a regular expression. The syntax of regular expressions is the same as in [Hyperscan UDF](../../udf/list/hyperscan.md) and [REGEXP](../../syntax/expressions.md#regexp).
+
+**Syntax**
+
+```
+<expression> like_regex <regexp string> [flag <flag string>]
+```
+
+Where:
+
+1. `<expression>` is a JsonPath expression with strings to be checked for matching the regular expression.
+2. `<regexp string>` is a string with the regular expression.
+3. `flag <flag string>` is an optional section where `<flag string>` is a string with regular expression execution flags.
+
+Supported flags:
+
+- `i`: Disable the case sensitivity.
+
+**Execution**
+
+Before the check, the input sequence arrays are automatically unpacked.
+
+After that, for each element of the input sequence:
+
+1. A check is made to find out if a string matches a regular expression.
+2. If the element isn't a string, the `ERROR` flag is set.
+3. If the check result is true, the `FOUND` flag is set.
+4. If either the `ERROR` or `FOUND` flag is set and the query is executed in `lax` mode, no more pairs are analyzed.
+
+If the pair analysis results in:
+
+1. Setting the `ERROR` flag, the predicate returns `null`
+2. Setting the `FOUND` flag, the predicate returns `true`
+3. Otherwise, the predicate returns `false`
+
+**Examples**
+
+1. `"123456" like_regex "^[0-9]+$"` returns `true`
+2. `"123abcd456" like_regex "^[0-9]+$"` returns `false`
+3. `"Naomi Nagata" like_regex "nag"` returns `false`
+4. `"Naomi Nagata" like_regex "nag" flag "i"` returns `true`
+
+#### `starts with`
+
+The `starts with` predicate lets you check if one string is a prefix of another.
+
+**Syntax**
+
+```
+<string expression> starts with <prefix expression>
+```
+
+Where:
+
+1. `<string expression>` is a JsonPath expression with the string to check.
+2. `<prefix expression>` is a JsonPath expression with a prefix string.
+
+This means that the predicate will check that the `<string expression>` starts with the `<prefix expression>` string.
+
+**Execution**
+
+The first argument of the predicate must be a single string.
+
+The second argument of the predicate must be a sequence of (possibly, multiple) strings.
+
+For each element in a sequence of prefix strings:
+
+1. A check is made for whether "an element is a prefix of an input string"
+2. If the element isn't a string, the `ERROR` flag is set.
+3. If the check result is true, the `FOUND` flag is set.
+4. If either the `ERROR` or `FOUND` flag is set and the query is executed in `lax` mode, no more pairs are analyzed.
+
+If the pair analysis results in:
+
+1. Setting the `ERROR` flag, the predicate returns `null`
+2. Setting the `FOUND` flag, the predicate returns `true`
+3. Otherwise, the predicate returns `false`
+
+**Examples**
+
+1. `"James Holden" starts with "James"` returns `true`
+2. `"James Holden" starts with "Amos"` returns `false`
+
+#### `exists`
+
+The `exists` predicate lets you check whether a JsonPath expression returns at least one element.
+
+**Syntax**
+
+```
+exists (<expression>)
+```
+
+Where `<expression>` is the JsonPath expression to be checked. Parentheses around the expression are required.
+
+**Execution**
+
+1. The passed JsonPath expression is executed
+2. If an error occurs, the predicate returns `null`
+3. If an empty sequence is obtained as a result of the execution, the predicate returns `false`
+4. Otherwise, the predicate returns `true`
+
+**Examples**
+
+Let's take a JSON document:
+
+```json
+{
+ "profile": {
+ "name": "Josephus",
+ "surname": "Miller"
+ }
+}
+```
+
+1. `exists ($.profile.name)` returns `true`
+2. `exists ($.friends.profile.name)` returns `false`
+3. `strict exists ($.friends.profile.name)` returns `null`, because accessing non-existent object keys in `strict` mode is an error.
+
+#### `is unknown`
+
+The `is unknown` predicate lets you check if a Boolean value is `null`.
+
+**Syntax**
+
+```
+(<expression>) is unknown
+```
+
+Where `<expression>` is the JsonPath expression to be checked. Only expressions that return a Boolean value are allowed. Parentheses around the expression are required.
+
+**Execution**
+
+1. If the passed expression returns `null`, the predicate returns `true`
+2. Otherwise, the predicate returns `false`
+
+**Examples**
+
+1. `(1 == 2) is unknown` returns `false`. The `1 == 2` expression returned `false`, which is not `null`
+2. `(1 == "string") is unknown` returns `true`. The `1 == "string"` expression returned `null`, because strings and numbers can't be compared in JsonPath.
+
+### Filters
+
+JsonPath lets you filter values obtained during query execution.
+
+An expression in a filter must return a Boolean value.
+Before filtering, the input sequence arrays are automatically unpacked.
+
+For each element of the input sequence:
+
+1. The value of the current filtered `@` object becomes equal to the current element of the input sequence.
+2. Executing the expression in the filter
+3. If an error occurs during the expression execution, the current element of the input sequence is skipped.
+4. If the expression execution result is the only `true` value, the current element is added to the filter result.
+
+**Example:**
+
+Suppose we have a JSON document describing the user's friends
+
+```json
+{
+ "friends": [
+ {
+ "name": "James Holden",
+ "age": 35,
+ "money": 500
+ },
+ {
+ "name": "Naomi Nagata",
+ "age": 30,
+ "money": 345
+ }
+ ]
+}
+```
+
+and we want to get a list of friends who are over 32 years old using a JsonPath query. To do this, you can write the following query:
+
+```
+$.friends ? (@.age > 32)
+```
+
+Let's analyze the query in parts:
+
+- `$.friends` accesses the `friends` array in the JSON document.
+- `? ( ... )` is the filter syntax. An expression inside the parentheses is called a predicate.
+- `` accesses the currently filtered object. In our example, it's the object describing a friend of the user.
+- `.age` accesses the `age` field of the currently filtered object.
+- `.age > 32` compares the `age` field with the value 32. As a result of the query, only the values for which this predicate returned true remain.
+
+The query only returns the first friend from the array of user's friends.
+
+Like many other JsonPath operators, filters can be arranged in chains. Let's take a more complex query that selects the names of friends who are older than 20 and have less than 400 currency units:
+
+```
+$.friends ? (@.age > 20) ? (@.money < 400) . name
+```
+
+Let's analyze the query in parts:
+
+- `$.friends` accesses the `friends` array in the JSON document.
+- `? (@.age > 20)` is the first filter. Since all friends are over 20, it just returns all the elements of the `friends` array.
+- `? (@.money < 400)` is the second filter. It only returns the second element of the `friends` array, since only its `money` field value is less than 400.
+- `.name` accesses the `name` field of filtered objects.
+
+The query returns a sequence of a single element: `"Naomi Nagata"`.
+
+In practice, it's recommended to combine multiple filters into one if possible. The above query is equivalent to `$.friends ? (@.age > 20 && @.money < 400) . name`.
+
+### Methods
+
+JsonPath supports methods that are functions converting one sequence of values to another. The syntax for calling a method is similar to accessing the object key:
+
+```
+$.friends.size()
+```
+
+Just like in the case of accessing object keys, method calls can be arranged in chains:
+
+```
+$.numbers.double().floor()
+```
+
+#### `type`
+
+The `type` method returns a string with the type of the passed value.
+
+For each element of the input sequence, the method adds this string to the output sequence according to the table below:
+
+| Value type | String with type |
+| ------------------ | ------------------------ |
+| Null | `"null"` |
+| Boolean value | `"boolean"` |
+| Number | `"number"` |
+| String | `"string"` |
+| Array | `"array"` |
+| Object | `"object"` |
+
+**Examples**
+
+1. `"Naomi".type()` returns `"string"`
+2. `false.type()` returns `"boolean"`
+
+#### `size`
+
+The `size` method returns the size of the array.
+
+For each element of the input sequence, the method adds the following to the output sequence:
+
+1. The size of the array if the element type is an array.
+2. For all other types (including objects), it adds `1`
+
+**Examples**
+
+Let's take a JSON document:
+
+```json
+{
+ "array": [1, 2, 3],
+ "object": {
+ "a": 1,
+ "b": 2
+ },
+ "scalar": "string"
+}
+```
+
+And queries to it:
+
+1. `$.array.size()` returns `3`
+2. `$.object.size()` returns `1`
+3. `$.scalar.size()` returns `1`
+
+#### `Double`
+
+The `double` method converts strings to numbers.
+
+Before its execution, the input sequence arrays are automatically unpacked.
+
+All elements in the input sequence must be strings that contain decimal numbers. It's allowed to specify the fractional part and exponent.
+
+**Examples**
+
+1. `"125".double()` returns `125`
+2. `"125.456".double()` returns `125.456`
+3. `"125.456e-3".double()` returns `0.125456`
+
+#### `ceiling`
+
+The `ceiling` method rounds up a number.
+
+Before its execution, the input sequence arrays are automatically unpacked.
+
+All elements in the input sequence must be numbers.
+
+**Examples**
+
+1. `(1.3).ceiling()` returns `2`
+2. `(1.8).ceiling()` returns `2`
+3. `(1.5).ceiling()` returns `2`
+4. `(1.0).ceiling()` returns `1`
+
+#### `floor`
+
+The `floor` method rounds down a number.
+
+Before its execution, the input sequence arrays are automatically unpacked.
+
+All elements in the input sequence must be numbers.
+
+**Examples**
+
+1. `(1.3).floor()` returns `1`
+2. `(1.8).floor()` returns `1`
+3. `(1.5).floor()` returns `1`
+4. `(1.0).floor()` returns `1`
+
+#### `abs`
+
+The `abs` method calculates the absolute value of a number (removes the sign).
+
+Before its execution, the input sequence arrays are automatically unpacked.
+
+All elements in the input sequence must be numbers.
+
+**Examples**
+
+1. `(0.0).abs()` returns `0`
+2. `(1.0).abs()` returns `1`
+3. `(-1.0).abs()` returns `1`
+
+#### `keyvalue`
+
+The `keyvalue` method converts an object to a sequence of key-value pairs.
+
+Before its execution, the input sequence arrays are automatically unpacked.
+
+All elements in the input sequence must be objects.
+
+For each element of the input sequence:
+
+1. Each key-value pair in the element is analyzed.
+2. For each key-value pair, an object is generated with the keys `name` and `value`.
+3. `name` stores a string with the name of the key from the pair.
+4. `value` stores the value from the pair.
+5. All objects for this element are added to the output sequence.
+
+**Examples**
+
+Let's take a JSON document:
+
+```json
+{
+ "name": "Chrisjen",
+ "surname": "Avasarala",
+ "age": 70
+}
+```
+
+The `$.keyvalue()` query returns the following sequence for it:
+
+```json
+{
+ "name": "age",
+ "value": 70
+},
+{
+ "name": "name",
+ "value": "Chrisjen"
+},
+{
+ "name": "surname",
+ "value": "Avasarala"
+}
+```
+
+### Variables
+
+Functions using JsonPath can pass values into a query. They are called variables. To access a variable, write the `$` character and the variable name: `$variable`.
+
+**Example:**
+
+Let the `planet` variable be equal to
+
+```json
+{
+ "name": "Mars",
+ "gravity": 0.376
+}
+```
+
+Then the `strict $planet.name` query returns `"Mars"`.
+
+Unlike many programming languages, JsonPath doesn't support creating new variables or modifying existing ones.
+
+## Common arguments
+
+All functions for JSON accept:
+
+1. A JSON value (can be an arbitrary `Json` or `Json?` expression)
+2. A JsonPath query (must be explicitly specified with a string literal)
+3. **(Optional)** `PASSING` section
+
+### PASSING section
+
+Lets you pass values to a JsonPath query as variables.
+
+**Syntax:**
+
+```yql
+PASSING
+ <expression 1> AS <variable name 1>,
+ <expression 2> AS <variable name 2>,
+ ...
+```
+
+`<expression>` can have the following types:
+
+- Numbers, `Date`, `DateTime`, and `Timestamp` (a `CAST` into `Double` will be made before passing a value to JsonPath)
+- `Utf8`, `Bool`, and `Json`
+
+You can set a `<variable name>` in several ways:
+
+- As an SQL name like `variable`
+- In quotes, for example, `"variable"`
+
+**Example:**
+
+```yql
+JSON_VALUE(
+ $json,
+ "$.timestamp - $Now + $Hour"
+ PASSING
+ 24 * 60 as Hour,
+ CurrentUtcTimestamp() as "Now"
+)
+```
+
+## JSON_EXISTS
+
+The `JSON_EXISTS` function checks if a JSON value meets the specified JsonPath.
+
+**Syntax:**
+
+```yql
+JSON_EXISTS(
+ <JSON expression>,
+ <JsonPath query>,
+ [<PASSING clause>]
+ [{TRUE | FALSE | UNKNOWN | ERROR} ON ERROR]
+)
+```
+
+**Return value:** `Bool?`
+
+**Default value:** If the `ON ERROR` section isn't specified, the used section is `FALSE ON ERROR`
+
+**Behavior:**
+
+1. If `<JSON expression>` is `NULL` or an empty `Json?`, it returns an empty `Bool?`
+2. If an error occurs during JsonPath execution, the returned value depends on the `ON ERROR` section:
+ - `TRUE`: Return `True`
+ - `FALSE`: Return `False`
+ - `UNKNOWN`: Return an empty `Bool?`
+ - `ERROR`: Abort the entire query
+3. If the result of JsonPath execution is one or more values, the return value is `True`.
+4. Otherwise, `False` is returned.
+
+**Examples:**
+
+```yql
+$json = CAST(@@{
+ "title": "Rocinante",
+ "crew": [
+ "James Holden",
+ "Naomi Nagata",
+ "Alex Kamai",
+ "Amos Burton"
+ ]
+}@@ as Json);
+
+SELECT
+ JSON_EXISTS($json, "$.title"), -- True
+ JSON_EXISTS($json, "$.crew[*]"), -- True
+ JSON_EXISTS($json, "$.nonexistent"); -- False, as JsonPath returns an empty result
+
+SELECT
+ -- JsonPath error, False is returned because the default section used is FALSE ON ERROR
+ JSON_EXISTS($json, "strict $.nonexistent");
+
+SELECT
+ -- JsonPath error, the entire YQL query fails.
+ JSON_EXISTS($json, "strict $.nonexistent" ERROR ON ERROR);
+```
+
+## JSON_VALUE
+
+The `JSON_VALUE` function retrieves a scalar value from JSON (anything that isn't an array or object).
+
+**Syntax:**
+
+```yql
+JSON_VALUE(
+ <JSON expression>,
+ <JsonPath query>,
+ [<PASSING clause>]
+ [RETURNING <type>]
+ [{ERROR | NULL | DEFAULT <expr>} ON EMPTY]
+ [{ERROR | NULL | DEFAULT <expr>} ON ERROR]
+)
+```
+
+**Return value:** `<type>?`
+
+**Default values:**
+
+1. If the `ON EMPTY` section isn't specified, the section used is `NULL ON EMPTY`
+2. If the `ON ERROR` section isn't specified, the section used is `NULL ON ERROR`
+3. If the `RETURNING` section isn't specified, then for `<type>`, the type used is `Utf8`
+
+**Behavior:**
+
+1. If `<JSON expression>` is `NULL` or an empty `Json?`, it returns an empty `<type>?`
+2. If an error occurs, the returned value depends on the `ON ERROR` section:
+ - `NULL`: Return an empty `<type>?`
+ - `ERROR`: Abort the entire query
+ - `DEFAULT <expr>`: Return `<expr>` after running the `CAST` function to convert the data type to `<type>?`. If the `CAST` fails, the entire query fails, too.
+3. If the JsonPath execution result is empty, the returned value depends on the `ON EMPTY` section:
+ - `NULL`: Return an empty `<type>?`
+ - `ERROR`: Abort the entire query
+ - `DEFAULT <expr>`: Return `<expr>` after running the `CAST` function to convert the data type to `<type>?`. If the `CAST` fails, the behavior matches the `ON ERROR` section.
+4. If the result of JsonPath execution is a single value, then:
+ - If the `RETURNING` section isn't specified, the value is converted to `Utf8`.
+ - Otherwise, the `CAST` function is run to convert the value to `<type>`. If the `CAST` fails, the behavior matches the `ON ERROR` section. In this case, the value from JSON must match the `<type>` type.
+5. Return the result
+
+Correlation between JSON and YQL types:
+
+- JSON Number: Numeric types, `Date`, `DateTime`, and `Timestamp`
+- JSON Bool: `Bool`
+- JSON String: `Utf8` and `String`
+
+Errors executing `JSON_VALUE` are as follows:
+
+- Errors evaluating JsonPath
+- The result of JsonPath execution is a number of values or a non-scalar value.
+- The type of value returned by JSON doesn't match the expected one.
+
+`The RETURNING` section supports such types as numbers, `Date`, `DateTime`, `Timestamp`, `Utf8`, `String`, and `Bool`.
+
+**Examples:**
+
+```yql
+$json = CAST(@@{
+ "friends": [
+ {
+ "name": "James Holden",
+ "age": 35
+ },
+ {
+ "name": "Naomi Nagata",
+ "age": 30
+ }
+ ]
+}@@ as Json);
+
+SELECT
+ JSON_VALUE($json, "$.friends[0].age"), -- "35" (type Utf8?)
+ JSON_VALUE($json, "$.friends[0].age" RETURNING Uint64), -- 35 (type Uint64?)
+ JSON_VALUE($json, "$.friends[0].age" RETURNING Utf8); -- an empty Utf8? due to an error. The JSON's Number type doesn't match the string Utf8 type.
+
+SELECT
+ -- "empty" (type String?)
+ JSON_VALUE(
+ $json,
+ "$.friends[50].name"
+ RETURNING String
+ DEFAULT "empty" ON EMPTY
+ );
+
+SELECT
+ -- 20 (type Uint64?). The result of JsonPath execution is empty, but the
+ -- default value from the ON EMPTY section can't be cast to Uint64.
+ -- That's why the value from ON ERROR is used.
+ JSON_VALUE(
+ $json,
+ "$.friends[50].age"
+ RETURNING Uint64
+ DEFAULT -1 ON EMPTY
+ DEFAULT 20 ON ERROR
+ );
+```
+
+## JSON_QUERY
+
+The `JSON_QUERY` function lets you retrieve arrays and objects from JSON.
+
+**Syntax:**
+
+```yql
+JSON_QUERY(
+ <JSON expression>,
+ <JsonPath query>,
+ [<PASSING clause>]
+ [WITHOUT [ARRAY] | WITH [CONDITIONAL | UNCONDITIONAL] [ARRAY] WRAPPER]
+ [{ERROR | NULL | EMPTY ARRAY | EMPTY OBJECT} ON EMPTY]
+ [{ERROR | NULL | EMPTY ARRAY | EMPTY OBJECT} ON ERROR]
+)
+```
+
+**Return value:** `Json?`
+
+**Default values:**
+
+1. If the `ON EMPTY` section isn't specified, the section used is `NULL ON EMPTY`
+2. If the `ON ERROR` section isn't specified, the section used is `NULL ON ERROR`
+3. If the `WRAPPER` section isn't specified, the section used is `WITHOUT WRAPPER`
+4. If the `WITH WRAPPER` section is specified but `CONDITIONAL` or `UNCONDITIONAL` is omitted, then the section used is `UNCONDITIONAL`
+
+**Behavior:**
+
+{% note info %}
+
+You can't specify the `WITH ... WRAPPER` and `ON EMPTY` sections at the same time.
+
+{% endnote %}
+
+1. If `<JSON expression>` is `NULL` or an empty `Json?`, it returns an empty `Json?`
+2. If the `WRAPPER` section is specified, then:
+ - `WITHOUT WRAPPER` or `WITHOUT ARRAY WRAPPER`: Don't convert the result of JsonPath execution in any way.
+ - `WITH UNCONDITIONAL WRAPPER` or `WITH UNCONDITIONAL ARRAY WRAPPER`: Wrap the result of JsonPath execution in an array.
+ - `WITH CONDITIONAL WRAPPER` or `WITH CONDITIONAL ARRAY WRAPPER`: Wrap the result of JsonPath execution in an array if it isn't the only array or object.
+3. If the JsonPath execution result is empty, the returned value depends on the `ON EMPTY` section:
+ - `NULL`: Return an empty `Json?`
+ - `ERROR`: Abort the entire query
+ - `EMPTY ARRAY`: Return an empty JSON array, `[]`
+ - `EMPTY OBJECT`: Return an empty JSON object, `{}`
+4. If an error occurs, the returned value depends on the `ON ERROR` section:
+ - `NULL`: Return an empty `Json?`
+ - `ERROR`: Abort the entire query
+ - `EMPTY ARRAY`: Return an empty JSON array, `[]`
+ - `EMPTY OBJECT`: Return an empty JSON object, `{}`
+5. Return the result
+
+Errors running a `JSON_QUERY`:
+
+- Errors evaluating JsonPath
+- The result of JsonPath execution is a number of values (even after using the `WRAPPER` section) or a scalar value.
+
+**Examples:**
+
+```yql
+$json = CAST(@@{
+ "friends": [
+ {
+ "name": "James Holden",
+ "age": 35
+ },
+ {
+ "name": "Naomi Nagata",
+ "age": 30
+ }
+ ]
+}@@ as Json);
+
+SELECT
+ JSON_QUERY($json, "$.friends[0]"); -- {"name": "James Holden", "age": 35}
+
+SELECT
+ JSON_QUERY($json, "$.friends.name" WITH UNCONDITIONAL WRAPPER); -- ["James Holden", "Naomi Nagata"]
+
+SELECT
+ JSON_QUERY($json, "$.friends[0]" WITH CONDITIONAL WRAPPER), -- {"name": "James Holden", "age": 35}
+ JSON_QUERY($json, "$.friends.name" WITH CONDITIONAL WRAPPER); -- ["James Holden", "Naomi Nagata"]
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/list.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/list.md
new file mode 100644
index 00000000000..e28ccca28e8
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/list.md
@@ -0,0 +1,544 @@
+# Functions for lists
+
+## ListCreate {#list-create}
+
+Construct an empty list. The only argument specifies a string describing the data type of the list cell, or the type itself obtained using [relevant functions](../types.md). YQL doesn't support lists with an unknown cell type.
+
+[Documentation for the type definition format](../../types/type_string.md).
+
+**Examples**
+
+```yql
+SELECT ListCreate(Tuple<String,Double?>);
+```
+
+```yql
+SELECT ListCreate(OptionalType(DataType("String")));
+```
+
+## AsList and AsListStrict {#aslist}
+
+Construct a list based on one or more arguments. The argument types must be compatible in the case of `AsList` and strictly match in the case of `AsListStrict`.
+
+**Examples**
+
+```yql
+SELECT AsList(1, 2, 3, 4, 5);
+```
+
+## ListLength {#listlength}
+
+The count of items in the list.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT ListLength(list_column) FROM my_table;
+```
+
+{% endif %}
+
+## ListHasItems
+
+Check that the list contains at least one item.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT ListHasItems(list_column) FROM my_table;
+```
+
+{% endif %}
+
+## ListCollect {#listcollect}
+
+Convert a lazy list (it can be built by such functions as [ListFilter](#listfilter), [ListMap](#listmap), [ListFlatMap](#listflatmap)) to an eager list. In contrast to a lazy list, where each new pass re-calculates the list contents, in an eager list the content is built at once by consuming more memory.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT ListCollect(list_column) FROM my_table;
+```
+
+{% endif %}
+
+## ListSort, ListSortAsc, and ListSortDesc {#listsort}
+
+Sort the list. By default, the ascending sorting order is applied (`ListSort` is an alias for `ListSortAsc`).
+
+Arguments:
+
+1. List.
+2. An optional expression to get the sort key from a list element (it's the element itself by default).
+
+**Examples**
+
+{% if feature_column_container_type %}
+
+```yql
+SELECT ListSortDesc(list_column) FROM my_table;
+```
+
+{% endif %}
+
+```yql
+$list = AsList(
+ AsTuple("x", 3),
+ AsTuple("xx", 1),
+ AsTuple("a", 2)
+);
+
+SELECT ListSort($list, ($x) -> {
+ RETURN $x.1;
+});
+```
+
+{% note info %}
+
+The example used a [lambda function](../../syntax/expressions.md#lambda).
+
+{% endnote %}
+
+## ListExtend and ListExtendStrict {#listextend}
+
+Sequentially join lists (concatenation of lists). The arguments can be lists, optional lists, and `NULL`.
+The types of list items must be compatible in the case of `ListExtend` and strictly match in the case of `ListExtendStrict`.
+If at least one of the lists is optional, then the result is also optional.
+If at least one argument is `NULL`, then the result type is `NULL`.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT ListExtend(
+ list_column_1,
+ list_column_2,
+ list_column_3
+) FROM my_table;
+```
+
+{% endif %}
+
+## ListUnionAll {#listunionall}
+
+Sequentially join lists of structures (concatenation of lists). A field is added to the output list of structures if it exists in at least one source list, but if there is no such field in any list, it is added as NULL. In the case when a field is present in two or more lists, the output field is cast to the common type.
+
+If at least one of the lists is optional, then the result is also optional.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT ListUnionAll(
+ list_column_1,
+ list_column_2,
+ list_column_3
+) FROM my_table;
+```
+
+{% endif %}
+
+## ListZip and ListZipAll {#listzip}
+
+Based on the input lists, build a list of pairs containing the list items with matching indexes (`List<Tuplefirst_list_element_type,second_list_element_type>`).
+
+The length of the returned list is determined by the shortest list for ListZip and the longest list for ListZipAll.
+When the shorter list is exhausted, a `NULL` value of a relevant [optional type](../../types/optional.md) is paired with the elements of the longer list.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ListZip(list_column_1, list_column_2, list_column_3),
+ ListZipAll(list_column_1, list_column_2)
+FROM my_table;
+```
+
+{% endif %}
+
+## ListEnumerate {#listenumerate}
+
+Build a list of pairs (Tuple) containing the element number and the element itself (`List<TupleUint64,list_element_type>`).
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT ListEnumerate(list_column) FROM my_table;
+```
+
+{% endif %}
+
+## ListReverse {#listreverse}
+
+Reverse the list.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT ListReverse(list_column) FROM my_table;
+```
+
+{% endif %}
+
+## ListSkip {#listskip}
+
+Returns a copy of the list, skipping the specified number of its first elements.
+
+The first argument specifies the source list and the second argument specifies how many elements to skip.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ListSkip(list_column, 3)
+FROM my_table;
+```
+
+{% endif %}
+
+## ListTake {#listtake}
+
+Returns a copy of the list containing a limited number of elements from the second list.
+
+The first argument specifies the source list and the second argument specifies the maximum number of elements to be taken from the beginning of the list.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT ListTake(list_column, 3) FROM my_table;
+```
+
+{% endif %}
+
+## ListIndexOf {#listindexof}
+
+Searches the list for an element with the specified value and returns its index at the first occurrence. Indexes count from 0. If such element is missing, it returns `NULL`.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ListIndexOf(list_column, 123)
+FROM my_table;
+```
+
+{% endif %}
+
+## ListMap, ListFilter, and ListFlatMap {#listmap}
+
+Apply the function specified as the second argument to each list element. The functions differ in their returned result:
+
+* `ListMap` returns a list with results.
+* `ListFlatMap` returns a list with results, combining and expanding the first level of results (lists or optional values) for each item.
+* `ListFilter` leaves only those elements where the function returned `true`.
+
+{% note info %}
+
+In `ListFlatMap`, using optional values in function results is deprecated, use the combination of [`ListNotNull`](#listnotnull) and `ListMap` instead.
+
+{% endnote %}
+
+Arguments:
+
+1. Source list.
+2. Functions for processing list elements, such as:
+ * [Lambda function](../../syntax/expressions.md#lambda).
+ * `Module::Function` - C++ UDF.
+{% if feature_udf_noncpp %}
+ * [Python UDF](../../udf/python.md), [JavaScript UDF](../../udf/javascript.md) or any other called value.
+
+If the source list is optional, then the output list is also optional.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+$callable = Python::test(Callable<(Int64)->Bool>, "defMyFavouriteCrutchtest(i): return i % 2");
+SELECT
+ ListMap(list_column, ($x) -> { RETURN $x > 2; }),
+ ListFlatMap(list_column, My::Udf),
+ ListFilter(list_column, $callable)
+FROM my_table;
+```
+
+{% endif %}
+{% endif %}
+
+## ListNotNull {#listnotnull}
+
+Applies transformation to the source list, skipping empty optional items and strengthening the item type to non-optional. For a list with non-optional items, it returns the unchanged source list.
+
+If the source list is optional, then the output list is also optional.
+
+**Examples**
+
+```yql
+SELECT ListNotNull([1,2]), -- [1,2]
+ ListNotNull([3,null,4]); -- [3,4]
+```
+
+## ListFlatten {#listflatten}
+
+Expands the list of lists into a flat list, preserving the order of items. As the top-level list item you can use an optional list that is interpreted as an empty list in the case of `NULL`.
+
+If the source list is optional, then the output list is also optional.
+
+**Examples**
+
+```yql
+SELECT ListFlatten([[1,2],[3,4]]), -- [1,2,3,4]
+ ListFlatten([null,[3,4],[5,6]]); -- [3,4,5,6]
+```
+
+## ListUniq {#listuniq}
+
+Returns a copy of the list containing only distinct elements.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ListUniq(list_column)
+FROM my_table;
+```
+
+{% endif %}
+
+## ListAny and ListAll {#listany}
+
+Returns `true` for a list of Boolean values, if:
+
+* `ListAny`: At least one element is `true`.
+* `ListAll`: All elements are `true`.
+
+Otherwise, it returns false.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ListAll(bool_column),
+ ListAny(bool_column)
+FROM my_table;
+```
+
+{% endif %}
+
+## ListHas {#listhas}
+
+Show whether the list contains the specified element.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ListHas(list_column, "my_needle")
+FROM my_table;
+```
+
+{% endif %}
+
+## ListHead, ListLast {#listheadlast}
+
+Returns the first and last item of the list.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ListHead(numeric_list_column) AS head,
+ ListLast(numeric_list_column) AS last
+FROM my_table;
+```
+
+{% endif %}
+
+## ListMin, ListMax, ListSum and ListAvg {#listminy}
+
+Apply the appropriate aggregate function to all elements of the numeric list.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ListMax(numeric_list_column) AS max,
+ ListMin(numeric_list_column) AS min,
+ ListSum(numeric_list_column) AS sum,
+ ListAvg(numeric_list_column) AS avg
+FROM my_table;
+```
+
+{% endif %}
+
+## ListFromRange {#listfromrange}
+
+Generate a sequence of numbers with the specified step. It's similar to `xrange` in Python 2, but additionally supports floats.
+
+Arguments:
+
+1. Start
+2. End
+3. Step (optional, 1 by default)
+
+Specifics:
+
+* The end is not included, i.e. `ListFromRange(1,3) == AsList(1,2)`.
+* The type for the resulting elements is selected as the broadest from the argument types. For example, `ListFromRange(1, 2, 0.5)` results in a `Double` list.
+* The list is "lazy", but if it's used incorrectly, it can still consume a lot of RAM.
+* If the step is positive and the end is less than or equal to the start, the result list is empty.
+* If the step is negative and the end is greater than or equal to the start, the result list is empty.
+* If the step is neither positive nor negative (0 or NaN), the result list is empty.
+
+**Examples**
+
+```yql
+SELECT
+ ListFromRange(-2, 2), -- [-2, -1, 0, 1]
+ ListFromRange(2, 1, -0.5); -- [2.0, 1.5]
+```
+
+## ListReplicate {#listreplicate}
+
+Creates a list containing multiple copies of the specified value.
+
+Required arguments:
+
+1. Value.
+2. Number of copies.
+
+**Examples**
+
+```yql
+SELECT ListReplicate(true, 3); -- [true, true, true]
+```
+
+## ListConcat {#listconcat}
+
+Concatenates a list of strings into a single string.
+You can set a separator as the second parameter.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ListConcat(string_list_column),
+ ListConcat(string_list_column, "; ")
+FROM my_table;
+```
+
+{% endif %}
+
+## ListExtract {#listextract}
+
+For a list of structures, it returns a list of contained fields having the specified name.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ListExtract(struct_list_column, "MyMember")
+FROM my_table;
+```
+
+{% endif %}
+
+## ListTakeWhile, ListSkipWhile {#listtakewhile}
+
+`ListTakeWhile` returns a list from the beginning while the predicate is true, then the list ends.
+
+`ListSkipWhile` skips the list segment from the beginning while the predicate is true, then returns the rest of the list ignoring the predicate.
+`ListTakeWhileInclusive` returns a list from the beginning while the predicate is true. Then the list ends, but it also includes the item on which the stopping predicate triggered.
+`ListSkipWhileInclusive` skips a list segment from the beginning while the predicate is true, then returns the rest of the list disregarding the predicate, but excluding the element that matched the predicate and starting with the next element after it.
+
+Required arguments:
+
+1. List.
+2. Predicate.
+
+If the input list is optional, then the result is also optional.
+
+**Examples**
+
+```yql
+$data = AsList(1, 2, 5, 1, 2, 7);
+
+SELECT
+ ListTakeWhile($data, ($x) -> {return $x <= 3}), -- [1, 2]
+ ListSkipWhile($data, ($x) -> {return $x <= 3}), -- [5, 1, 2, 7]
+ ListTakeWhileInclusive($data, ($x) -> {return $x <= 3}), -- [1, 2, 5]
+ ListSkipWhileInclusive($data, ($x) -> {return $x <= 3}); -- [1, 2, 7]
+```
+
+## ListAggregate {#listaggregate}
+
+Apply the [aggregation factory](../basic.md#aggregationfactory) to the passed list.
+If the passed list is empty, the aggregation result is the same as for an empty table: 0 for the `COUNT` function and `NULL` for other functions.
+If the passed list is optional and `NULL`, the result is also `NULL`.
+
+Arguments:
+
+1. List.
+2. [Aggregation factory](../basic.md#aggregationfactory).
+
+**Examples**
+
+```yql
+SELECT ListAggregate(AsList(1, 2, 3), AggregationFactory("Sum")); -- 6
+```
+
+## ToDict and ToMultiDict {#todict}
+
+Convert a list of tuples containing key-value pairs to a dictionary. In case of conflicting keys in the input list, `ToDict` leaves the first value and `ToMultiDict` builds a list of all the values.
+
+It means that:
+
+* `ToDict` converts `List<TupleK, V="">` to `Dict<K, V="">`
+* `ToMultiDict` converts `List<TupleK, V>` to `Dict<K, List<V>>`
+
+Optional lists are also supported, resulting in an optional dictionary.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ToDict(tuple_list_column)
+FROM my_table;
+```
+
+{% endif %}
+
+## ToSet {#toset}
+
+Converts a list to a dictionary where the keys are unique elements of this list, and values are omitted and have the type `Void`. For the `List<T>` list, the result type is `Dict<T, Void="">`.
+An optional list is also supported, resulting in an optional dictionary.
+
+Inverse function: get a list of keys for the [DictKeys](../dict.md#dictkeys) dictionary.
+
+**Examples**
+{% if feature_column_container_type %}
+
+```yql
+SELECT
+ ToSet(list_column)
+FROM my_table;
+```
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/struct.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/struct.md
new file mode 100644
index 00000000000..1b824272b7e
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/struct.md
@@ -0,0 +1,320 @@
+# Functions for structures
+
+## TryMember {#trymember}
+
+Trying to get a field from the structure. If it's not found among the fields or null in the structure value, use the default value.
+
+Arguments:
+
+1. Structure.
+2. Field name.
+3. Default value.
+
+```yql
+$struct = <|a:1|>;
+SELECT
+ TryMember(
+ $struct,
+ "a",
+ 123
+ ) AS a, -- 1
+ TryMember(
+ $struct,
+ "b",
+ 123
+ ) AS b; -- 123
+```
+
+## ExpandStruct {#expandstruct}
+
+Adding one or more new fields to the structure.
+
+If the field set contains duplicate values, an error is returned.
+
+Arguments:
+
+* The first argument passes the source structure to be expanded.
+* All the other arguments must be named, each argument adds a new field and the argument's name is used as the field's name (as in [AsStruct](../basic.md#asstruct)).
+
+**Examples**
+
+```yql
+$struct = <|a:1|>;
+SELECT
+ ExpandStruct(
+ $struct,
+ 2 AS b,
+ "3" AS c
+ ) AS abc;
+```
+
+## AddMember {#addmember}
+
+Adding one new field to the structure. If you need to add multiple fields, better use [ExpandStruct](#expandstruct).
+
+If the field set contains duplicate values, an error is returned.
+
+Arguments:
+
+1. Source structure.
+2. Name of the new field.
+3. Value of the new field.
+
+**Examples**
+
+```yql
+$struct = <|a:1|>;
+SELECT
+ AddMember(
+ $struct,
+ "b",
+ 2
+ ) AS ab;
+```
+
+## RemoveMember {#removemember}
+
+Removing a field from the structure.
+
+If the entered field hasn't existed, an error is returned.
+
+Arguments:
+
+1. Source structure.
+2. Field name.
+
+**Examples**
+
+```yql
+$struct = <|a:1, b:2|>;
+SELECT
+ RemoveMember(
+ $struct,
+ "b"
+ ) AS a;
+```
+
+## ForceRemoveMember {#forceremovemember}
+
+Removing a field from the structure.
+
+If the entered field hasn't existed, unlike [RemoveMember](#removemember), the error is not returned.
+
+Arguments:
+
+1. Source structure.
+2. Field name.
+
+**Examples**
+
+```yql
+$struct = <|a:1, b:2|>;
+SELECT
+ ForceRemoveMember(
+ $struct,
+ "c"
+ ) AS ab;
+```
+
+## ChooseMembers {#choosemembers}
+
+Selecting fields with specified names from the structure.
+
+If any of the fields haven't existed, an error is returned.
+
+Arguments:
+
+1. Source structure.
+2. List of field names.
+
+**Examples**
+
+```yql
+$struct = <|a:1, b:2, c:3|>;
+SELECT
+ ChooseMembers(
+ $struct,
+ ["a", "b"]
+ ) AS ab;
+```
+
+## RemoveMembers {#removemembers}
+
+Excluding fields with specified names from the structure.
+
+If any of the fields haven't existed, an error is returned.
+
+Arguments:
+
+1. Source structure.
+2. List of field names.
+
+**Examples**
+
+```yql
+$struct = <|a:1, b:2, c:3|>;
+SELECT
+ RemoveMembers(
+ $struct,
+ ["a", "b"]
+ ) AS c;
+```
+
+## ForceRemoveMembers {#forceremovemembers}
+
+Excluding fields with specified names from the structure.
+
+If any of the fields haven't existed, it is ignored.
+
+Arguments:
+
+1. Source structure.
+2. List of field names.
+
+**Examples**
+
+```yql
+$struct = <|a:1, b:2, c:3|>;
+SELECT
+ ForceRemoveMembers(
+ $struct,
+ ["a", "b", "z"]
+ ) AS c;
+```
+
+## CombineMembers {#combinemembers}
+
+Combining the fields from multiple structures into a new structure.
+
+If the resulting field set contains duplicate values, an error is returned.
+
+Arguments: two or more structures.
+
+**Examples**
+
+```yql
+$struct1 = <|a:1, b:2|>;
+$struct2 = <|c:3|>;
+SELECT
+ CombineMembers(
+ $struct1,
+ $struct2
+ ) AS abc;
+```
+
+## FlattenMembers {#flattenmembers}
+
+Combining the fields from multiple new structures into another new structure with prefix support.
+
+If the resulting field set contains duplicate values, an error is returned.
+
+Arguments: two or more tuples of two items: prefix and structure.
+
+**Examples**
+
+```yql
+$struct1 = <|a:1, b:2|>;
+$struct2 = <|c:3|>;
+SELECT
+ FlattenMembers(
+ AsTuple("foo", $struct1), -- fooa, foob
+ AsTuple("bar", $struct2) -- barc
+ ) AS abc;
+```
+
+## StructMembers {#structmembers}
+
+Returns an unordered list of field names (possibly removing one Optional level) for a single argument that is a structure. For the `NULL` argument, an empty list of strings is returned.
+
+Argument: structure
+
+**Examples**
+
+```yql
+$struct = <|a:1, b:2|>;
+SELECT
+ StructMembers($struct); -- ['a', 'b']
+```
+
+## RenameMembers {#renamemembers}
+
+Renames the fields in the structure passed. In this case, you can rename a source field into multiple target fields. All fields not mentioned in the renaming as source names are moved to the result structure. If some source field is omitted in the rename list, an error is returned. For an Optional structure or `NULL`, the result has the same type.
+
+Arguments:
+
+1. Source structure.
+2. A tuple of field names: the original name, the new name.
+
+**Examples**
+
+```yql
+$struct = <|a:1, b:2|>;
+SELECT
+ RenameMembers($struct, [('a', 'c'), ('a', 'e')]); -- (b:2, c:1, e:1)
+```
+
+## ForceRenameMembers {#forecerenamemembers}
+
+Renames the fields in the structure passed. In this case, you can rename a source field into multiple target fields. All fields not mentioned in the renaming as source names are moved to the result structure. If some source field is omitted in the rename list, the name is ignored. For an Optional structure or `NULL`, the result has the same type.
+
+Arguments:
+
+1. Source structure.
+2. A tuple of field names: the original name, the new name.
+
+**Examples**
+
+```yql
+$struct = <|a:1, b:2|>;
+SELECT
+ ForceRenameMembers($struct, [('a', 'c'), ('d', 'e')]); -- (b:2, c:1)
+```
+
+## GatherMembers {#gathermembers}
+
+Returns an unordered list of tuples including the field name and value. For the `NULL` argument, `EmptyList` is returned. It can be used only in the cases when the types of items in the structure are the same or compatible. Returns an optional list for an optional structure.
+
+Argument: structure
+
+**Examples**
+
+```yql
+$struct = <|a:1, b:2|>;
+SELECT
+ GatherMembers($struct); -- [('a', 1), ('b', 2)]
+```
+
+## SpreadMembers {#spreadmembers}
+
+Creates a structure with a specified list of fields and applies a specified list of edits to it in the format (field name, field value). All types of fields in the resulting structure are the same and equal to the type of values in the update list with added Optional (unless they are optional already). If the field wasn't mentioned among the list of updated fields, it's returned as `NULL`. Among all updates for a field, the latest one is written. If the update list is Optional or `NULL`, the result has the same type. If the list of edits includes a field that is not in the list of expected fields, an error is returned.
+
+Arguments:
+
+1. List of tuples: field name, field value.
+2. A list of all possible field names in the structure.
+
+**Examples**
+
+```yql
+
+SELECT
+ SpreadMembers([('a',1),('a',2)],['a','b']); -- (a: 2, b: null)
+```
+
+## ForceSpreadMembers {#forcespreadmembers}
+
+Creates a structure with a specified list of fields and applies to it the specified list of updates in the format (field name, field value). All types of fields in the resulting structure are the same and equal to the type of values in the update list with added Optional (unless they are optional already). If the field wasn't mentioned among the list of updated fields, it's returned as `NULL`. Among all updates for a field, the latest one is written. If the update list is optional or equal to `NULL`, the result has the same type. If the list of updates includes a field that is not in the list of expected fields, this edit is ignored.
+
+Arguments:
+
+1. List of tuples: field name, field value.
+2. A list of all possible field names in the structure.
+
+**Examples**
+
+```yql
+
+SELECT
+ ForceSpreadMembers([('a',1),('a',2),('c',100)],['a','b']); -- (a: 2, b: null)
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/types.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/types.md
new file mode 100644
index 00000000000..152d4ba455d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/types.md
@@ -0,0 +1,630 @@
+# Functions for data types
+
+## FormatType {#formattype}
+
+Serializing a type {% if feature_codegen %} or a handle type{% endif %} to a human-readable string. This helps at debugging and will also be used in the next examples of this section. [Documentation for the format](../../types/type_string.md).
+
+## ParseType {#parsetype}
+
+Building a type from a string with description. [Documentation for its format](../../types/type_string.md).
+
+**Examples**
+
+```yql
+SELECT FormatType(ParseType("List<Int32>")); -- List<int32>
+```
+
+## TypeOf {#typeof}
+
+Getting the type of value passed to the argument.
+
+**Examples**
+
+```yql
+SELECT FormatType(TypeOf("foo")); -- String
+```
+
+```yql
+SELECT FormatType(TypeOf(AsTuple(1, 1u))); -- Tuple<Int32,Uint32>
+```
+
+## InstanceOf {#instanceof}
+
+Returns an instance of the specified type that can only be used to get the type of the result of an expression that uses this type.
+
+If this instance remains in the computation graph by the end of optimization, the operation fails.
+
+**Examples**
+
+```yql
+SELECT FormatType(TypeOf(
+ InstanceOf(ParseType("Int32")) +
+ InstanceOf(ParseType("Double"))
+)); -- Double, because "Int32 + Double" returns Double
+```
+
+## DataType {#datatype}
+
+Returns a type for [primitive data types](../../types/primitive.md) based on type name.
+
+**Examples**
+
+```yql
+SELECT FormatType(DataType("Bool")); -- Bool
+SELECT FormatType(DataType("Decimal","5","1")); -- Decimal(5,1)
+```
+
+## OptionalType {#optionaltype}
+
+Adds the option to assign `NULL` to the passed type.
+
+**Examples**
+
+```yql
+SELECT FormatType(OptionalType(DataType("Bool"))); -- Bool?
+```
+
+## ListType and StreamType {#listtype}
+
+Builds a list type or stream type based on the passed element type.
+
+**Examples**
+
+```yql
+SELECT FormatType(ListType(DataType("Bool"))); -- List<Bool>
+```
+
+## DictType {#dicttype}
+
+Builds a dictionary type based on the passed key types (first argument) and value types (second argument).
+
+**Examples**
+
+```yql
+SELECT FormatType(DictType(
+ DataType("String"),
+ DataType("Double")
+)); -- Dict<String,Double>
+```
+
+## TupleType {#tupletype}
+
+Builds the tuple type from the passed element types.
+
+**Examples**
+
+```yql
+SELECT FormatType(TupleType(
+ DataType("String"),
+ DataType("Double"),
+ OptionalType(DataType("Bool"))
+)); -- Tuple<String,Double,Bool?>
+```
+
+## StructType {#structtype}
+
+Builds the structure type based on the passed element types. The standard syntax of named arguments is used to specify the element names.
+
+**Examples**
+
+```yql
+SELECT FormatType(StructType(
+ DataType("Bool") AS MyBool,
+ ListType(DataType("String")) AS StringList
+)); -- Struct<'MyBool':Bool,'StringList':List<String>>
+```
+
+## VariantType {#varianttype}
+
+Returns the type of a variant based on the underlying type (structure or tuple).
+
+**Examples**
+
+```yql
+SELECT FormatType(VariantType(
+ ParseType("Struct<foo:Int32,bar:Double>")
+)); -- Variant<'bar':Double,'foo':Int32>
+```
+
+## ResourceType {#resourcetype}
+
+Returns the type of the [resource](../../types/special.md) based on the passed string label.
+
+**Examples**
+
+```yql
+SELECT FormatType(ResourceType("Foo")); -- Resource<'Foo'>
+```
+
+## CallableType {#callabletype}
+
+Constructs the type of the called value using the following arguments:
+
+1. Number of optional arguments (if all arguments are required — 0).
+2. Result type.
+3. All the next arguments of CallableType are treated as types of arguments of the callable value, but with a shift for two required arguments (for example, the third argument of the CallableType describes the type of the first argument in the callable value).
+
+**Examples**
+
+```yql
+SELECT FormatType(CallableType(
+ 1, -- optional args count
+ DataType("Double"), -- result type
+ DataType("String"), -- arg #1 type
+ OptionalType(DataType("Int64")) -- arg #2 type
+)); -- Callable<(String,[Int64?])->Double>
+```
+
+## GenericType, UnitType, and VoidType {#generictype}
+
+Return the same-name [special data types](../../types/special.md). They have no arguments because they are not parameterized.
+
+**Examples**
+
+```yql
+SELECT FormatType(VoidType()); -- Void
+```
+
+## OptionalItemType, ListItemType and StreamItemType {#optionalitemtype}
+
+{% if feature_codegen %} If a type is passed to these functions, then they perform {% else %}Perform{% endif %} the action reverse to [OptionalType](#optionaltype), [ListType](#listtype), and [StreamType](#streamtype): return the item type based on its container type.
+{% if feature_codegen %}
+If a type handle is passed to these functions, then they perform the action reverse to [OptionalTypeHandle](#optionaltypehandle), [ListTypeHandle](#listtypehandle), and [StreamTypeHandle](#streamtypehandle): they return the handle of the element type based on the type handle of its container.{% endif %}
+
+**Examples**
+
+```yql
+SELECT FormatType(ListItemType(
+ ParseType("List<Int32>")
+)); -- Int32
+```
+
+{% if feature_codegen %}
+
+```yql
+SELECT FormatType(ListItemType(
+ ParseTypeHandle("List<Int32>")
+)); -- Int32
+```
+
+{% endif %}
+
+## DictKeyType and DictPayloadType {#dictkeytype}
+
+Returns the type of the key or value based on the dictionary type.
+
+**Examples**
+
+```yql
+SELECT FormatType(DictKeyType(
+ ParseType("Dict<Int32,String>")
+)); -- Int32
+```
+
+## TupleElementType {#tupleelementtype}
+
+Returns the tuple's element type based on the tuple type and the element index (index starts from zero).
+
+**Examples**
+
+```yql
+SELECT FormatType(TupleElementType(
+ ParseType("Tuple<Int32,Double>"), "1"
+)); -- Double
+```
+
+## StructMemberType {#structmembertype}
+
+Returns the type of the structure element based on the structure type and element name.
+
+**Examples**
+
+```yql
+SELECT FormatType(StructMemberType(
+ ParseType("Struct<foo:Int32,bar:Double>"), "foo"
+)); -- Int32
+```
+
+## CallableResultType and CallableArgumentType {#callableresulttype}
+
+`CallableResultType` returns the result type based on the type of the called value. `CallableArgumentType` returns the argument type based on the called value type and its index (index starts from zero).
+
+**Examples**
+
+```yql
+$callable_type = ParseType("(String,Bool)->Double");
+
+SELECT FormatType(CallableResultType(
+ $callable_type
+)), -- Double
+FormatType(CallableArgumentType(
+ $callable_type, 1
+)); -- Bool
+```
+
+## VariantUnderlyingType {#variantunderlyingtype}
+
+{% if feature_codegen %}If a type is passed to this function, then it {% else %}Performs{% endif %} an action reverse to [VariantType](#varianttype): it returns the underlying type based on the variant type.
+{% if feature_codegen %}
+If a type handle is passed to this function, it performs the action reverse to [VariantTypeHandle](#varianttypehandle): returns the handle of the underlying type based on the handle of the variant type.{% endif %}
+
+**Examples**
+
+```yql
+SELECT FormatType(VariantUnderlyingType(
+ ParseType("Variant<foo:Int32,bar:Double>")
+)), -- Struct<'bar':Double,'foo':Int32>
+FormatType(VariantUnderlyingType(
+ ParseType("Variant<Int32,Double>")
+)); -- Tuple<Int32,Double>
+```
+
+{% if feature_codegen %}
+
+```yql
+SELECT FormatType(VariantUnderlyingType(
+ ParseTypeHandle("Variant<foo:Int32,bar:Double>")
+)), -- Struct<'bar':Double,'foo':Int32>
+FormatType(VariantUnderlyingType(
+ ParseTypeHandle("Variant<Int32,Double>")
+)); -- Tuple<Int32,Double>
+```
+
+{% endif %}
+
+{% if feature_codegen %}
+
+# Functions for data types during calculations
+
+To work with data types during calculations, use handle types: these are [resources](../../types/special.md) that contain an opaque type definition. After constructing the type handle, you can revert to the regular type using the [EvaluateType](#evaluatetype) function. For debug purposes, you can convert a handle type to a string using the [FormatType](#formattype) function.
+
+## TypeHandle
+
+Getting a type handle from the type passed to the argument.
+
+**Examples:**
+
+```yql
+SELECT FormatType(TypeHandle(TypeOf("foo"))); -- String
+```
+
+## EvaluateType
+
+Getting the type from the type handle passed to the argument. The function is evaluated before the start of the main calculation, as well as [EvaluateExpr](../basic.md#evaluate_expr_atom).
+
+**Examples:**
+
+```yql
+SELECT FormatType(EvaluateType(TypeHandle(TypeOf("foo")))); -- String
+```
+
+## ParseTypeHandle
+
+Building a type handle from a string with description. [Documentation for its format](../../types/type_string.md).
+
+**Examples:**
+
+```yql
+SELECT FormatType(ParseTypeHandle("List<Int32>")); -- List<int32>
+```
+
+## TypeKind
+
+Getting the top-level type name from the type handle passed to the argument.
+
+**Examples:**
+
+```yql
+SELECT TypeKind(TypeHandle(TypeOf("foo"))); -- Data
+SELECT TypeKind(ParseTypeHandle("List<Int32>")); -- List
+```
+
+## DataTypeComponents
+
+Getting the name and parameters for a [primitive data type](../../types/primitive.md) from the primitive type handle passed to the argument. Reverse function: [DataTypeHandle](#datatypehandle).
+
+**Examples:**
+
+```yql
+SELECT DataTypeComponents(TypeHandle(TypeOf("foo"))); -- ["String"]
+SELECT DataTypeComponents(ParseTypeHandle("Decimal(4,1)")); -- ["Decimal", "4", "1"]
+```
+
+## DataTypeHandle
+
+Constructing a handle for a [primitive data type](../../types/primitive.md) from its name and parameters passed to the argument as a list. Reverse function: [DataTypeComponents](#datatypecomponents).
+
+**Examples:**
+
+```yql
+SELECT FormatType(DataTypeHandle(
+ AsList("String")
+)); -- String
+
+SELECT FormatType(DataTypeHandle(
+ AsList("Decimal", "4", "1")
+)); -- Decimal(4,1)
+```
+
+## OptionalTypeHandle
+
+Adds the option to assign `NULL` to the passed type handle.
+
+**Examples:**
+
+```yql
+SELECT FormatType(OptionalTypeHandle(
+ TypeHandle(DataType("Bool"))
+)); -- Bool?
+```
+
+## ListTypeHandle and StreamTypeHandle {#list-stream-typehandle}
+
+Builds a list type handle or stream type handle based on the passed element type handle.
+
+**Examples:**
+
+```yql
+SELECT FormatType(ListTypeHandle(
+ TypeHandle(DataType("Bool"))
+)); -- List<Bool>
+```
+
+## EmptyListTypeHandle and EmptyDictTypeHandle
+
+Constructs a handle for an empty list or dictionary.
+
+**Examples:**
+
+```yql
+SELECT FormatType(EmptyListTypeHandle()); -- EmptyList
+```
+
+## TupleTypeComponents
+
+Getting a list of element type handles from the tuple type handle passed to the argument. Inverse function: [TupleTypeHandle](#tupletypehandle).
+
+**Examples:**
+
+```yql
+SELECT ListMap(
+ TupleTypeComponents(
+ ParseTypeHandle("Tuple<Int32, String>")
+ ),
+ ($x)->{
+ return FormatType($x)
+ }
+); -- ["Int32", "String"]
+```
+
+## TupleTypeHandle
+
+Building a tuple type handle from handles of element types passed as a list to the argument. Inverse function: [TupleTypeComponents](#tupletypecomponents).
+
+**Examples:**
+
+```yql
+SELECT FormatType(
+ TupleTypeHandle(
+ AsList(
+ ParseTypeHandle("Int32"),
+ ParseTypeHandle("String")
+ )
+ )
+); -- Tuple<Int32,String>
+```
+
+## StructTypeComponents
+
+Getting a list of element type handles and their names from the structure type handle passed to the argument. Inverse function: [StructTypeHandle](#structtypehandle).
+
+**Examples:**
+
+```yql
+SELECT ListMap(
+ StructTypeComponents(
+ ParseTypeHandle("Struct<a:Int32, b:String>")
+ ),
+ ($x) -> {
+ return AsTuple(
+ FormatType($x.Type),
+ $x.Name
+ )
+ }
+); -- [("Int32","a"), ("String","b")]
+```
+
+## StructTypeHandle
+
+Building a structure type handle from handles of element types and names passed as a list to the argument. Inverse function: [StructTypeComponents](#structtypecomponents).
+
+**Examples:**
+
+```yql
+SELECT FormatType(
+ StructTypeHandle(
+ AsList(
+ AsStruct(ParseTypeHandle("Int32") as Type,"a" as Name),
+ AsStruct(ParseTypeHandle("String") as Type, "b" as Name)
+ )
+ )
+); -- Struct<'a':Int32,'b':String>
+```
+
+## DictTypeComponents
+
+Getting a key-type handle and a value-type handle from the dictionary-type handle passed to the argument. Inverse function: [DictTypeHandle](#dicttypehandle).
+
+**Examples:**
+
+```yql
+$d = DictTypeComponents(ParseTypeHandle("Dict<Int32,String>"));
+
+SELECT
+ FormatType($d.Key), -- Int32
+ FormatType($d.Payload); -- String
+```
+
+## DictTypeHandle
+
+Building a dictionary-type handle from a key-type handle and a value-type handle passed to arguments. Inverse function: [DictTypeComponents](#dicttypecomponents).
+
+**Examples:**
+
+```yql
+SELECT FormatType(
+ DictTypeHandle(
+ ParseTypeHandle("Int32"),
+ ParseTypeHandle("String")
+ )
+); -- Dict<Int32, String>
+```
+
+## ResourceTypeTag
+
+Getting the tag from the resource type handle passed to the argument. Inverse function: [ResourceTypeHandle](#resourcetypehandle).
+
+**Examples:**
+
+```yql
+SELECT ResourceTypeTag(ParseTypeHandle("Resource<foo>")); -- foo
+```
+
+## ResourceTypeHandle
+
+Building a resource-type handle from the tag value passed to the argument. Inverse function: [ResourceTypeTag](#resourcetypetag).
+
+**Examples:**
+
+```yql
+SELECT FormatType(ResourceTypeHandle("foo")); -- Resource<'foo'>
+```
+
+## TaggedTypeComponents
+
+Getting the tag and the basic type from the decorated type handle passed to the argument. Inverse function: [TaggedTypeHandle](#taggedtypehandle).
+
+**Examples:**
+
+```yql
+$t = TaggedTypeComponents(ParseTypeHandle("Tagged<Int32,foo>"));
+
+SELECT FormatType($t.Base), $t.Tag; -- Int32, foo
+```
+
+## TaggedTypeHandle
+
+Constructing a decorated type handle based on the base type handle and the tag name passed in arguments. Inverse function: [TaggedTypeComponents](#taggedtypecomponents).
+
+**Examples:**
+
+```yql
+SELECT FormatType(TaggedTypeHandle(
+ ParseTypeHandle("Int32"), "foo"
+)); -- Tagged<Int32, 'foo'>
+```
+
+## VariantTypeHandle
+
+Building a variant-type handle from the handle of the underlying type passed to the argument. Inverse function: [VariantUnderlyingType](#variantunderlyingtype).
+
+**Examples:**
+
+```yql
+SELECT FormatType(VariantTypeHandle(
+ ParseTypeHandle("Tuple<Int32, String>")
+)); -- Variant<Int32, String>
+```
+
+## VoidTypeHandle and NullTypeHandle
+
+Constructing a handle for Void and Null types, respectively.
+
+**Examples:**
+
+```yql
+SELECT FormatType(VoidTypeHandle()); -- Void
+SELECT FormatType(NullTypeHandle()); -- Null
+```
+
+## CallableTypeComponents
+
+Getting the handle description for the type of callable value passed to the argument. Inverse function: [CallableTypeHandle](#callabletypehandle).
+
+**Examples:**
+
+```yql
+$formatArgument = ($x) -> {
+ return AsStruct(
+ FormatType($x.Type) as Type,
+ $x.Name as Name,
+ $x.Flags as Flags
+ )
+};
+
+$formatCallable = ($x) -> {
+ return AsStruct(
+ $x.OptionalArgumentsCount as OptionalArgumentsCount,
+ $x.Payload as Payload,
+ FormatType($x.Result) as Result,
+ ListMap($x.Arguments, $formatArgument) as Arguments
+ )
+};
+
+SELECT $formatCallable(
+ CallableTypeComponents(
+ ParseTypeHandle("(Int32,[bar:Double?{Flags:AutoMap}])->String")
+ )
+); -- (OptionalArgumentsCount: 1, Payload: "", Result: "String", Arguments: [
+ -- (Type: "Int32", Name: "", Flags: []),
+ -- (Type: "Double?", Name: "bar", Flags: ["AutoMap"]),
+ -- ])
+```
+
+## CallableArgument
+
+Packing the description of the argument of the callable value into the structure to be passed to the [CallableTypeHandle](#callabletypehandle) function with the following arguments:
+
+1. Argument type handle.
+2. Optional argument name. The default value is an empty string.
+3. A list of strings with optional argument flags. The default value is an empty list. Supported flags are "AutoMap".
+
+## CallableTypeHandle
+
+Constructing the type handle of the called value using the following arguments:
+
+1. Handle of the return value type.
+2. List of descriptions of arguments received using the [CallableArgument](#callableargument) function.
+3. Optional number of optional arguments in the callable value. The default value is 0.
+4. An optional label for the called value type. The default value is an empty string.
+
+Inverse function: [CallableTypeComponents](#callabletypecomponents).
+
+**Examples:**
+
+```yql
+SELECT FormatType(
+ CallableTypeHandle(
+ ParseTypeHandle("String"),
+ AsList(
+ CallableArgument(ParseTypeHandle("Int32")),
+ CallableArgument(ParseTypeHandle("Double?"), "bar", AsList("AutoMap"))
+ ),
+ 1
+ )
+); -- Callable<(Int32,['bar':Double?{Flags:AutoMap}])->String>
+```
+
+## LambdaArgumentsCount
+
+Getting the number of arguments in a lambda function.
+
+**Examples:**
+
+```yql
+SELECT LambdaArgumentsCount(($x, $y)->($x+$y))
+; -- 2
+```
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/aggregate.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/aggregate.md
new file mode 100644
index 00000000000..6f5f78cdfba
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/aggregate.md
@@ -0,0 +1,17 @@
+## Aggregate functions {#aggregate-functions}
+
+All [aggregate functions](../../aggregation.md) can also be used as window functions.
+In this case, each row includes an aggregation result obtained on a set of rows from the [window frame](../../../syntax/window.md#frame).
+
+**Examples:**
+
+```yql
+SELECT
+ SUM(int_column) OVER w1 AS running_total,
+ SUM(int_column) OVER w2 AS total,
+FROM my_table
+WINDOW
+ w1 AS (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
+ w2 AS ();
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/first_last_value.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/first_last_value.md
new file mode 100644
index 00000000000..a3dc0c052bf
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/first_last_value.md
@@ -0,0 +1,22 @@
+## FIRST_VALUE / LAST_VALUE
+
+Access values from the first and last rows of the [window frame](../../../syntax/window.md#frame). The only argument is the expression that you need to access.
+
+Optionally, `OVER` can be preceded by the additional modifier `IGNORE NULLS`. It changes the behavior of functions to the first or last __non-empty__ (i.e., non-`NULL`) value among the window frame rows. The antonym of this modifier is `RESPECT NULLS`: it's the default behavior that can be omitted.
+
+**Examples**
+
+```yql
+SELECT
+ FIRST_VALUE(my_column) OVER w
+FROM my_table
+WINDOW w AS (ORDER BY key);
+```
+
+```yql
+SELECT
+ LAST_VALUE(my_column) IGNORE NULLS OVER w
+FROM my_table
+WINDOW w AS (ORDER BY key);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/intro.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/intro.md
new file mode 100644
index 00000000000..f1f627c3e93
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/intro.md
@@ -0,0 +1,4 @@
+# List of window functions in YQL
+
+The syntax for calling window functions is detailed in a [separate article](../../../syntax/window.md).
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/lag_lead.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/lag_lead.md
new file mode 100644
index 00000000000..334d448fedd
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/lag_lead.md
@@ -0,0 +1,13 @@
+## LAG / LEAD {#lag-lead}
+
+Accessing a value from a row in the [section](../../../syntax/window.md#partition) that lags behind (`LAG`) or leads (`LEAD`) the current row by a fixed number. The first argument specifies the expression to be accessed, and the second argument specifies the offset in rows. You may omit the offset. By default, the neighbor row is used: the previous or next, respectively (hence, 1 is assumed by default). For the rows having no neighbors at a given distance (for example `LAG(expr, 3)` `NULL` is returned in the first and second rows of the section.
+
+**Examples**
+
+```yql
+SELECT
+ int_value - LAG(int_value) OVER w AS int_value_diff
+FROM my_table
+WINDOW w AS (ORDER BY key);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/rank_dense.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/rank_dense.md
new file mode 100644
index 00000000000..88e66e32d07
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/rank_dense.md
@@ -0,0 +1,29 @@
+## RANK / DENSE_RANK {#rank}
+
+Number the groups of neighboring rows in the [section](../../../syntax/window.md#partition) that have the same expression value in the argument. `DENSE_RANK` numbers the groups one-by-one, and `RANK` skips `(N - 1)` values, with `N` being the number of rows in the previous group.
+
+If there is no argument, it uses the order specified in the `ORDER BY` section in the window definition.
+If the argument is omitted and `ORDER BY` is not specified, then all rows are considered equal to each other.
+
+{% note info %}
+
+Passing an argument to `RANK`/`DENSE_RANK` is a non-standard extension in YQL.
+
+{% endnote %}
+
+**Examples**
+
+```yql
+SELECT
+ RANK(my_column) OVER w
+FROM my_table
+WINDOW w AS (ORDER BY key);
+```
+
+```yql
+SELECT
+ RANK() OVER w
+FROM my_table
+WINDOW w AS (ORDER BY my_column);
+
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/row_number.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/row_number.md
new file mode 100644
index 00000000000..49c93db7fc2
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/row_number.md
@@ -0,0 +1,13 @@
+## ROW_NUMBER {#row_number}
+
+Row number within a [partition](../../../syntax/window.md#partition). No arguments.
+
+**Examples**
+
+```yql
+SELECT
+ ROW_NUMBER() OVER w AS row_num
+FROM my_table
+WINDOW w AS (ORDER BY key);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/session_state.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/session_state.md
new file mode 100644
index 00000000000..241d78b7445
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/_includes/window/session_state.md
@@ -0,0 +1,5 @@
+## SessionState() {#session-state}
+
+A non-standard window function `SessionState()` (without arguments) lets you get the session calculation status from [SessionWindow](../../../syntax/group_by.md#session-window) for the current row.
+It's allowed only if `SessionWindow()` is present in the `PARTITION BY` section in the window definition.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/aggregation.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/aggregation.md
new file mode 100644
index 00000000000..2d6f0e1f606
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/aggregation.md
@@ -0,0 +1,29 @@
+{% include [simple.md](_includes/aggregation/simple.md) %}
+
+{% include [count_distinct_estimate.md](_includes/aggregation/count_distinct_estimate.md) %}
+
+{% include [agg_list.md](_includes/aggregation/agg_list.md) %}
+
+{% include [max_min_by.md](_includes/aggregation/max_min_by.md) %}
+
+{% include [top_bottom.md](_includes/aggregation/top_bottom.md) %}
+
+{% include [topfreq_mode.md](_includes/aggregation/topfreq_mode.md) %}
+
+{% include [stddev_variance.md](_includes/aggregation/stddev_variance.md) %}
+
+{% include [corr_covar.md](_includes/aggregation/corr_covar.md) %}
+
+{% include [percentile_median.md](_includes/aggregation/percentile_median.md) %}
+
+{% include [histogram.md](_includes/aggregation/histogram.md) %}
+
+{% include [bool_bit.md](_includes/aggregation/bool_bit.md) %}
+
+{% if feature_window_functions %}
+
+ {% include [session_start.md](_includes/aggregation/session_start.md) %}
+
+{% endif %}
+
+{% include [aggregate_by.md](_includes/aggregation/aggregate_by.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/basic.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/basic.md
new file mode 100644
index 00000000000..b4262430aac
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/basic.md
@@ -0,0 +1,92 @@
+
+{% include [x](_includes/basic/intro.md) %}
+
+{% include [x](_includes/basic/coalesce.md) %}
+
+{% include [x](_includes/basic/length.md) %}
+
+{% include [x](_includes/basic/substring.md) %}
+
+{% include [x](_includes/basic/find.md) %}
+
+{% include [x](_includes/basic/starts_ends_with.md) %}
+
+{% include [x](_includes/basic/if.md) %}
+
+{% include [x](_includes/basic/nanvl.md) %}
+
+{% include [x](_includes/basic/random.md) %}
+
+{% include [x](_includes/basic/current_utc.md) %}
+
+{% include [x](_includes/basic/current_tz.md) %}
+
+{% include [x](_includes/basic/max_min.md) %}
+
+{% include [x](_includes/basic/as_container.md) %}
+
+{% include [x](_includes/basic/container_literal.md) %}
+
+{% include [x](_includes/basic/variant.md) %}
+
+{% include [x](_includes/basic/enum.md) %}
+
+{% include [x](_includes/basic/as_tagged.md) %}
+
+{% if feature_bulk_tables %}
+
+ {% include [x](_includes/basic/table_path_name_recindex.md) %}
+
+{% endif %}
+
+{% include [x](_includes/basic/table_row.md) %}
+
+{% if feature_mapreduce %}
+
+ {% include [x](_includes/basic/files.md) %}
+
+ {% include [x](_includes/basic/weakfield.md) %}
+
+{% endif %}
+
+{% include [x](_includes/basic/ensure.md) %}
+
+{% if feature_codegen %}
+
+ {% include [x](_includes/basic/evaluate_expr_atom.md) %}
+
+{% endif %}
+
+{% include [x](_includes/basic/data-type-literals.md) %}
+
+{% if feature_webui %}
+
+ {% include [x](_includes/basic/metadata.md) %}
+
+{% endif %}
+
+{% include [x](_includes/basic/to_from_bytes.md) %}
+
+{% include [x](_includes/basic/byteat.md) %}
+
+{% include [x](_includes/basic/bitops.md) %}
+
+{% include [x](_includes/basic/abs.md) %}
+
+{% include [x](_includes/basic/optional_ops.md) %}
+
+{% include [x](_includes/basic/callable.md) %}
+
+{% include [x](_includes/basic/pickle.md) %}
+
+{% include [x](_includes/basic/staticmap.md) %}
+
+{% include [x](_includes/basic/staticzip.md) %}
+
+{% include [x](_includes/basic/aggr_factory.md) %}
+
+{% if tech %}
+
+ {% include [x](_includes/basic/s_expressions.md) %}
+
+{% endif %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/codegen.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/codegen.md
new file mode 100644
index 00000000000..bc3bca2b116
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/codegen.md
@@ -0,0 +1,2 @@
+
+{% include [codegen.md](_includes/codegen.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/dict.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/dict.md
new file mode 100644
index 00000000000..24267d59a41
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/dict.md
@@ -0,0 +1,2 @@
+
+{% include [dict.md](_includes/dict.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/index.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/index.md
new file mode 100644
index 00000000000..b3cf50bcae9
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/index.md
@@ -0,0 +1,2 @@
+
+{% include [index.md](_includes/index.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/json.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/json.md
new file mode 100644
index 00000000000..4b454b1b634
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/json.md
@@ -0,0 +1,2 @@
+
+{% include [json.md](_includes/json.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/list.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/list.md
new file mode 100644
index 00000000000..a312392cda9
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/list.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/list.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/struct.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/struct.md
new file mode 100644
index 00000000000..418289d2530
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/struct.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/struct.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/toc_i.yaml b/ydb/docs/en/core/yql/reference/yql-core/builtins/toc_i.yaml
new file mode 100644
index 00000000000..9481cd1ccc1
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/toc_i.yaml
@@ -0,0 +1,13 @@
+items:
+- { name: Overview, href: index.md }
+- { name: Basic, href: basic.md }
+- { name: Aggregate, href: aggregation.md }
+- { name: Window, href: window.md, when: feature_window_functions }
+- { name: For lists, href: list.md }
+- { name: For dictionaries, href: dict.md }
+- { name: For structures, href: struct.md }
+- { name: For types, href: types.md }
+- { name: For code generation, href: codegen.md, when: feature_codegen }
+- { name: For JSON, href: json.md }
+- name: C++ libraries
+ include: { mode: link, path: ../udf/list/toc_i.yaml } \ No newline at end of file
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/types.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/types.md
new file mode 100644
index 00000000000..962e7b5fe24
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/types.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/types.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/builtins/window.md b/ydb/docs/en/core/yql/reference/yql-core/builtins/window.md
new file mode 100644
index 00000000000..bd2e7be6c3b
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/builtins/window.md
@@ -0,0 +1,14 @@
+
+{% include [x](_includes/window/intro.md) %}
+
+{% include [x](_includes/window/aggregate.md) %}
+
+{% include [x](_includes/window/row_number.md) %}
+
+{% include [x](_includes/window/lag_lead.md) %}
+
+{% include [x](_includes/window/first_last_value.md) %}
+
+{% include [x](_includes/window/rank_dense.md) %}
+
+{% include [x](_includes/window/session_state.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_assets/join-YQL-06.png b/ydb/docs/en/core/yql/reference/yql-core/syntax/_assets/join-YQL-06.png
new file mode 100644
index 00000000000..88fb42f97fc
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_assets/join-YQL-06.png
Binary files differ
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/Readme.txt b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/Readme.txt
new file mode 100644
index 00000000000..3cc55b2121a
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/Readme.txt
@@ -0,0 +1,2 @@
+Files inside this folder represent YQL base blocks, and may NOT contain product-conditional content ({% if rtmr/ydb/yt/... == true %})
+It may not contain yandex-internal references either. \ No newline at end of file
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/begin.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/begin.md
new file mode 100644
index 00000000000..6858f824932
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/begin.md
@@ -0,0 +1,21 @@
+## BEGIN .. END DO {#begin}
+
+Performing an action without declaring it (anonymous action).
+
+**Syntax**
+
+1. `BEGIN`.
+1. List of top-level expressions.
+1. `END DO`.
+
+An anonymous action can't include any parameters.
+
+**Example**
+
+```
+DO BEGIN
+ SELECT 1;
+ SELECT 2 -- here and in the previous example, you might omit ';' before END
+END DO
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/define_do.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/define_do.md
new file mode 100644
index 00000000000..97ef941ee75
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/define_do.md
@@ -0,0 +1,51 @@
+## DEFINE ACTION {#define-action}
+
+Specifies a named action that is a parameterizable block of multiple top-level expressions.
+
+**Syntax**
+
+1. `DEFINE ACTION`: action definition.
+1. [Action name](../../expressions.md#named-nodes) that will be used to access the defined action further in the query.
+1. The values of parameter names are listed in parentheses.
+1. `AS` keyword.
+1. List of top-level expressions.
+1. `END DEFINE`: The marker of the last expression inside the action.
+
+One or more of the last parameters can be marked with a question mark `?` as optional. If they are omitted during the call, they will be assigned the `NULL` value.
+
+## DO {#do}
+
+Executes an `ACTION` with the specified parameters.
+
+**Syntax**
+
+1. `DO`: Executing an action.
+1. The named expression for which the action is defined.
+1. The values to be used as parameters are listed in parentheses.
+
+`EMPTY_ACTION`: An action that does nothing.
+
+{% if feature_mapreduce %} <!-- In fact, if user file system integration is supported in the product. YQL service over YDB may also be here. -->
+
+{% note info %}
+
+In large queries, you can use separate files for action definition and include them to the main query using [EXPORT](../../export_import.md#export) + [IMPORT](../../export_import.md#import) so that instead of one long text you can have several logical parts that are easier to navigate. An important nuance: the `USE my_cluster;` directive in the import query does not affect behavior of actions declared in other files.
+
+{% endnote %}
+
+{% endif %}
+
+**Example**
+
+```yql
+DEFINE ACTION $hello_world($name, $suffix?) AS
+ $name = $name ?? ($suffix ?? "world");
+ SELECT "Hello, " || $name || "!";
+END DEFINE;
+
+DO EMPTY_ACTION();
+DO $hello_world(NULL);
+DO $hello_world("John");
+DO $hello_world(NULL, "Earth");
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/evaluate.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/evaluate.md
new file mode 100644
index 00000000000..1a696689083
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/action/evaluate.md
@@ -0,0 +1,76 @@
+## EVALUATE IF {#evaluate-if}
+
+`EVALUATE IF`: Executing an action depending on the condition. It's followed by:
+
+1. Condition.
+2. [DO](#do) with the name and parameters of the action or an anonymous action.
+3. An optional `ELSE` followed by the second `DO` for a situation where the condition is not met.
+
+## EVALUATE FOR {#evaluate-for}
+
+`EVALUATE FOR`: Executing an action for each item in the list. It's followed by:
+
+1. [A named expression](../../expressions.md#named-nodes) applied to each next element in the list.
+2. `IN` keyword.
+3. The above-declared named expression applied to the list the action is executed on.
+4. [DO](#do) with the name and parameters of an action or an anonymous action. In the parameters, you can use both the current element from the first paragraph and any named expressions declared above, including the list itself.
+5. An optional `ELSE` followed by the second `DO` for the situation when the list is empty.
+
+**Examples**
+
+```yql
+DEFINE ACTION $hello() AS
+ SELECT "Hello!";
+END DEFINE;
+
+DEFINE ACTION $bye() AS
+ SELECT "Bye!";
+END DEFINE;
+
+EVALUATE IF RANDOM(0) > 0.5
+ DO $hello()
+ELSE
+ DO $bye();
+
+EVALUATE IF RANDOM(0) > 0.1 DO BEGIN
+ SELECT "Hello!";
+END DO;
+
+EVALUATE FOR $i IN AsList(1, 2, 3) DO BEGIN
+ SELECT $i;
+END DO;
+```
+
+```yql
+-- copy the $input table to $count of new tables
+$count = 3;
+$input = "my_input";
+$inputs = ListReplicate($input, $count);
+$outputs = ListMap(
+ ListFromRange(0, $count),
+ ($i) -> {
+ RETURN "tmp/out_" || CAST($i as String)
+ }
+);
+$pairs = ListZip($inputs, $outputs);
+
+DEFINE ACTION $copy_table($pair) as
+ $input = $pair.0;
+ $output = $pair.1;
+ INSERT INTO $output WITH TRUNCATE
+ SELECT * FROM $input;
+END DEFINE;
+
+EVALUATE FOR $pair IN $pairs
+ DO $copy_table($pair)
+ELSE
+ DO EMPTY_ACTION (); -- you may omit this ELSE,
+ -- do nothing is implied by default
+```
+
+{% note info %}
+
+Note that `EVALUATE` is run before the operation starts. Please also note that in `EVALUATE` you can't use [anonymous tables](../../select.md#temporary-tables).
+
+{% endnote %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/alter_table.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/alter_table.md
new file mode 100644
index 00000000000..f57d319135d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/alter_table.md
@@ -0,0 +1,139 @@
+# ALTER TABLE
+
+Using the ```ALTER TABLE``` command, you can change the composition of columns and additional table parameters. You can specify several actions in one command. In general, the ```ALTER TABLE``` command looks like this:
+
+```sql
+ALTER TABLE table_name action1, action2, ..., actionN;
+```
+
+```action```: Any action to change the table described below.
+
+## Changing the composition of columns {#columns}
+
+{{ backend_name }} lets you add columns to a table and delete non-key columns from it.
+
+```ADD COLUMN```: Adds a column with the specified name and type. The code below adds the ```is_deleted``` column with the ```Bool data``` type to the ```episodes``` table.
+
+```sql
+ALTER TABLE episodes ADD COLUMN is_deleted Bool;
+```
+
+```DROP COLUMN```: Deletes the column with the specified name. The code below removes the ```is_deleted``` column from the ```episodes``` table.
+
+```sql
+ALTER TABLE episodes DROP column is_deleted;
+```
+
+{% if feature_secondary_index %}
+
+## Adding or removing a secondary index {#secondary-index}
+
+```ADD INDEX```: Adds an index with the specified name and type for a given set of columns. The code below adds a global index named ```title_index``` for the ```title``` column.
+
+```sql
+ALTER TABLE `series` ADD INDEX `title_index` GLOBAL ON (`title`);
+```
+
+You can specify any index parameters from the [`CREATE TABLE`](../create_table#secondary_index) command.
+
+Deleting an index:
+
+```DROP INDEX```: Deletes the index with the specified name. The code below deletes the index named ```title_index```.
+
+```sql
+ALTER TABLE `series` DROP INDEX `title_index`;
+```
+
+{% endif %}
+{% if feature_map_tables %}
+
+## Renaming a table {#rename}
+
+```sql
+ALTER TABLE old_table_name RENAME TO new_table_name;
+```
+
+If a table with a new name exists, an error is returned. The possibility of transactional table substitution under load is supported by ad-hoc CLI and SDK methods.
+
+If a YQL query contains multiple `ALTER TABLE ... RENAME TO ...` commands, each of them will be executed in autocommit mode as a separate transaction. From the external process viewpoint, the tables will be renamed sequentially one by one. To rename multiple tables within a single transaction, use ad-hoc methods available in the CLI and SDK.
+
+Renaming can be used to move a table from one directory inside the database to another, for example:
+
+```sql
+ALTER TABLE `table1` RENAME TO `/backup/table1`;
+```
+
+## Changing column groups {#column-family}
+
+```ADD FAMILY```: Creates a new group of columns in the table. The code below creates the ```family_small``` column group in the ```series_with_families``` table.
+
+```sql
+ALTER TABLE series_with_families ADD FAMILY family_small (
+ DATA = "ssd",
+ COMPRESSION = "off"
+);
+```
+
+Using the ```ALTER COLUMN``` command, you can change a column group for the specified column. The code below for the ```release_date``` column in the ```series_with_families``` table changes the column group to ```family_small```.
+
+```sql
+ALTER TABLE series_with_families ALTER COLUMN release_date SET FAMILY family_small;
+```
+
+The two previous commands from listings 8 and 9 can be combined into one ```ALTER TABLE``` call. The code below creates the ```family_small``` column group and sets it for the ```release_date``` column in the ```series_with_families``` table.
+
+```sql
+ALTER TABLE series_with_families
+ ADD FAMILY family_small (
+ DATA = "ssd",
+ COMPRESSION = "off"
+ ),
+ ALTER COLUMN release_date SET FAMILY family_small;
+```
+
+Using the ```ALTER FAMILY``` command, you can change the parameters of the column group. The code below changes the storage type to ```hdd``` for the ```default``` column group in the ```series_with_families``` table:
+
+```sql
+ALTER TABLE series_with_families ALTER FAMILY default SET DATA "hdd";
+```
+
+You can specify any column family parameters from the [`CREATE TABLE`](create_table#column-family) command.
+
+## Changing additional table parameters {#additional-alter}
+
+Most of the table parameters in YDB described on the [table description]({{ concept_table }}) page can be changed with the ```ALTER``` command.
+
+In general, the command to change any table parameter looks like this:
+
+```sql
+ALTER TABLE table_name SET (key = value);
+```
+
+```key``` is a parameter name and ```value``` is its new value.
+
+For example, this command disables automatic partitioning of the table:
+
+```sql
+ALTER TABLE series SET (AUTO_PARTITIONING_BY_SIZE = DISABLED);
+```
+
+## Resetting additional table parameters {#additional-reset}
+
+Some table parameters in YDB listed on the [table description]({{ concept_table }}) page can be reset with the ```ALTER``` command.
+
+The command to reset the table parameter looks like this:
+
+```sql
+ALTER TABLE table_name RESET (key);
+```
+
+```key```: Name of the parameter.
+
+For example, this command resets (deletes) TTL settings for the table:
+
+```sql
+ALTER TABLE series RESET (TTL);
+```
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/create_table.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/create_table.md
new file mode 100644
index 00000000000..b4c5eb5f53f
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/create_table.md
@@ -0,0 +1,165 @@
+# CREATE TABLE
+
+{% if feature_bulk_tables %}
+
+The table is created automatically during the first [INSERT INTO](insert_into.md){% if feature_mapreduce %} in the database specified in [USE](../use.md){% endif %}. The schema is determined automatically.
+
+{% else %}
+
+The `CREATE TABLE` call creates a {% if concept_table %}[table]({{ concept_table }}){% else %}table{% endif %} with the specified data schema{% if feature_map_tables %} and key columns (`PRIMARY KEY`){% endif %}. {% if feature_secondary_index == true %}It lets you define secondary indexes on the created table.{% endif %}
+
+ CREATE TABLE table_name (
+ column1 type1,
+
+{% if feature_not_null == true %} column2 type2 NOT NULL,{% else %} column2 type2,{% endif %}
+...
+columnN typeN,
+{% if feature_secondary_index == true %}
+INDEX index1_name GLOBAL ON ( column ),
+INDEX index2_name GLOBAL ON ( column1, column2, ... ),
+{% endif %}
+{% if feature_map_tables %}
+PRIMARY KEY (column, ...),
+FAMILY column_family ()
+{% else %}
+...
+{% endif %}
+)
+{% if feature_map_tables %}
+WITH ( key = value, ... )
+{% endif %}
+
+## Columns {#columns}
+
+{% if feature_column_container_type == true %}
+In non-key columns, you can use any data types, but for key columns, only [primitive ones](../../types/primitive.md). When specifying complex types (for example, `List<String>`), the type is enclosed in double quotes.
+{% else %}
+For key columns and non-key columns, only [primitive](../../types/primitive.md) data types are allowed. {% endif %}
+
+{% if feature_not_null == true %}
+Without additional modifiers, the column is assigned the [optional type](../../types/optional.md) and can accept `NULL` values. To create a non-optional type, use `NOT NULL`.
+{% else %}
+All columns allow writing `NULL` values, that is, they are [optional](../../types/optional.md).
+{% endif %}
+{% if feature_map_tables %}
+It is mandatory to specify the `PRIMARY KEY` with a non-empty list of columns. Those columns become part of the key in the listed order.
+{% endif %}
+
+**Example**
+
+ CREATE TABLE my_table (
+ a Uint64,
+ b Bool,
+
+{% if feature_not_null %} c Float NOT NULL,{% else %} c Float,{% endif %}
+{% if feature_column_container_type %} d "List<List<Int32>>"{% endif %}
+{% if feature_map_tables %}
+PRIMARY KEY (b, a)
+{% endif %}
+)
+
+{% if feature_secondary_index %}
+
+## Secondary indexes {#secondary_index}
+
+The INDEX construct is used to define a {% if concept_secondary_index %}[secondary index]({{ concept_secondary_index }}){% else %}secondary index{% endif %} in a table:
+
+```sql
+CREATE TABLE table_name (
+ ...
+ INDEX <Index_name> GLOBAL [SYNC|ASYNC] ON ( <Index_columns> ) COVER ( <Cover_columns> ),
+ ...
+)
+```
+
+where:
+
+* **Index_name** is the unique name of the index to be used to access data.
+* **SYNC/ASYNC** indicates synchronous/asynchronous data writes to the index. If not specified, synchronous.
+* **Index_columns** is a list of comma-separated names of columns in the created table to be used for a search in the index.
+* **Cover_columns** is a list of comma-separated names of columns in the created table, which will be stored in the index in addition to the search columns, making it possible to fetch additional data without accessing the table for it.
+
+**Example**
+
+```sql
+CREATE TABLE my_table (
+ a Uint64,
+ b Bool,
+ c Uft8,
+ d Date,
+ INDEX idx_a GLOBAL ON (d),
+ INDEX idx_ca GLOBAL ASYNC ON (b, a) COVER ( c ),
+ PRIMARY KEY (a)
+)
+```
+
+{% endif %}
+
+{% if feature_map_tables and concept_table %}
+
+## Additional parameters {#additional}
+
+You can also specify a number of {{ backend_name }}-specific parameters for the table. When creating a table using YQL, such parameters are listed in the ```WITH``` section:
+
+```sql
+CREATE TABLE table_name (...)
+WITH (
+ key1 = value1,
+ key2 = value2,
+ ...
+)
+```
+
+Here, key is the name of the parameter and value is its value.
+
+For a list of possible parameter names and their values, see [{{ backend_name }} table description]({{ concept_table }}).
+
+For example, this code will create a table with enabled automatic partitioning by partition size and the preferred size of each partition is 512 MB:
+
+<small>Listing 4</small>
+
+```sql
+CREATE TABLE my_table (
+ id Uint64,
+ title Utf8,
+ PRIMARY KEY (id)
+)
+WITH (
+ AUTO_PARTITIONING_BY_SIZE = ENABLED,
+ AUTO_PARTITIONING_PARTITION_SIZE_MB = 512
+);
+```
+
+## Column groups {#column-family}
+
+Columns of the same table can be grouped to set the following parameters:
+
+* `DATA`: A storage type for the data in this column group. Acceptable values: ```ssd```, ```hdd```.
+* `COMPRESSION`: A data compression codec. Acceptable values: ```off```, ```lz4```.
+
+By default, all columns are in the same group named ```default```. If necessary, the parameters of this group can also be redefined.
+
+In the example below, for the created table, the ```family_large``` group of columns is added and set for the ```series_info``` column, and the parameters for the ```default``` group, which is set by default for all other columns, are also redefined.
+
+```sql
+CREATE TABLE series_with_families (
+ series_id Uint64,
+ title Utf8,
+ series_info Utf8 FAMILY family_large,
+ release_date Uint64,
+ PRIMARY KEY (series_id),
+ FAMILY default (
+ DATA = "ssd",
+ COMPRESSION = "off"
+ ),
+ FAMILY family_large (
+ DATA = "hdd",
+ COMPRESSION = "lz4"
+ )
+);
+```
+
+{% endif %}
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/declare/general.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/declare/general.md
new file mode 100644
index 00000000000..003af35c542
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/declare/general.md
@@ -0,0 +1,36 @@
+# DECLARE
+
+Declares a typed [named expression](../../expressions.md#named-nodes) whose value will be passed separately from the query text. With parameterization, you can separately develop an analytical solution and then launch it sequentially with different input values.
+
+In the case of transactional load, parameters let you avoid recompilation of queries when repeating calls of the same type. This way you can reduce server utilization and exclude compilation time from the total time of query execution.
+
+Passing of parameters is supported in the SDK, CLI, and graphical interfaces.
+
+**Syntax**
+
+```sql
+DECLARE $named-node AS data_type;
+```
+
+1. `DECLARE` keyword.
+1. `$named-node`: The name by which you can access the passed value. It must start with `$`.
+1. `AS` keyword.
+1. `data_type` is the data type [represented as a string in the accepted format](../../../types/type_string.md).
+
+Only serializable data types are allowed:
+
+* [Primitive types](../../../types/primitive.md).
+* [Optional types](../../../types/optional.md).
+* [Containers](../../../types/containers.md), except `Stream<Type>`.
+* `Void` and `Null` are the supported [special types](../../../types/special.md).
+
+**Example**
+
+```yql
+DECLARE $x AS String;
+DECLARE $y AS String?;
+DECLARE $z AS List<String>;
+
+SELECT $x, $y, $z;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/delete.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/delete.md
new file mode 100644
index 00000000000..2748b78e710
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/delete.md
@@ -0,0 +1,36 @@
+# DELETE FROM
+
+Deletes rows that match the `WHERE` clause, from the table.{% if feature_mapreduce %} The table is searched by name in the database specified by the [USE](../use.md) operator.{% endif %}
+
+{% note info %}
+
+The changes of the table state can't be tracked within a single transaction. If the table has already been changed, use [`DELETE ON`](#delete-on) to delete the data within the same transaction.
+
+{% endnote %}
+
+**Example**
+
+```sql
+DELETE FROM my_table
+WHERE Key1 == 1 AND Key2 >= "One";
+COMMIT;
+```
+
+## DELETE FROM ... ON {#delete-on}
+
+Used to delete the data, if the table has already been changed within the same transaction.
+
+**Example**
+
+```sql
+$to_delete = (
+ SELECT Key, SubKey FROM my_table WHERE Value = "ToDelete"
+);
+
+SELECT * FROM my_table;
+
+DELETE FROM my_table ON
+SELECT * FROM $to_delete;
+COMMIT;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/discard.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/discard.md
new file mode 100644
index 00000000000..9926069fc8f
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/discard.md
@@ -0,0 +1,30 @@
+# DISCARD
+
+Calculates {% if select_command == "SELECT STREAM" %}[`SELECT STREAM`](../select_stream.md){% else %}[`SELECT`](../select.md){% endif %}{% if feature_mapreduce %}{% if reduce_command %}, [`{{ reduce_command }}`](../reduce.md){% endif %}, or [`{{ process_command }}`](../process.md){% endif %} without returning the result neither to the client or table. {% if feature_mapreduce %}You can't use it along with [INTO RESULT](../into_result.md).{% endif %}
+
+It's good to combine it with [`Ensure`](../../builtins/basic.md#ensure) to check the final calculation result against the user's criteria.
+
+{% if select_command != true or select_command == "SELECT" %}
+**Examples**
+
+```yql
+DISCARD SELECT 1;
+```
+
+```yql
+INSERT INTO result_table WITH TRUNCATE
+SELECT * FROM
+my_table
+WHERE value % 2 == 0;
+
+COMMIT;
+
+DISCARD SELECT Ensure(
+ 0, -- will discard result anyway
+ COUNT(*) > 1000,
+ "Too small result table, got only " || CAST(COUNT(*) AS String) || " rows"
+) FROM result_table;
+```
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/drop_table.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/drop_table.md
new file mode 100644
index 00000000000..2cd4ad581cf
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/drop_table.md
@@ -0,0 +1,12 @@
+# DROP TABLE
+
+Deletes the specified table.{% if feature_mapreduce %} The table is searched by name in the database specified by the [USE](../use.md) operator.{% endif %}
+
+If there is no such table, an error is returned.
+
+**Examples:**
+
+```yql
+DROP TABLE my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/export_import.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/export_import.md
new file mode 100644
index 00000000000..116b4cc550b
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/export_import.md
@@ -0,0 +1,61 @@
+# Putting part of the query into a separate file
+
+Here's the mechanism for putting part of the query into a separate attached file:
+
+* [PRAGMA Library](../pragma.md#library) marks the attached file as available for import.
+
+## `Export`
+
+* `EXPORT $my_symbol1, $my_symbol2, ...;` lists the names of named expressions in the library that are available for import.
+
+## `Import`
+
+* `IMPORT my_library SYMBOLS $my_symbol1, $my_symbol2, ...;` makes the listed named expressions available for further use.
+
+{% note info %}
+
+You can use the library to include [lambdas](../expressions.md#lambda), [actions](../action.md){% if feature_subquery %}, [named subqueries](../subquery.md){% endif %}, constants and expressions, but __not subqueries or aggregate functions__.
+
+{% endnote %}
+
+{% note warning %}
+
+The file linked by the [PRAGMA Library](../pragma.md#library) must be attached to the query. __You can't use a [PRAGMA File](../pragma.md#file) for this purpose__.
+
+{% endnote %}
+
+**Examples:**
+
+my_lib.sql:
+
+```yql
+$Square = ($x) -> { RETURN $x * $x; };
+$Sqrt = ($x) -> { RETURN Math::Sqrt($x); };
+
+-- Aggregate functions created by
+-- AggregationFactory, it makes sense to add it to the library
+$Agg_sum = AggregationFactory("SUM");
+$Agg_max = AggregationFactory("MAX");
+
+EXPORT $Square, $Sqrt, $Agg_sum, $Agg_max;
+```
+
+Query:
+
+```yql
+PRAGMA Library("my_lib.sql");
+IMPORT my_lib SYMBOLS $Square, $Sqrt, $Agg_sum, $Agg_max;
+SELECT
+ $Square(2), -- 4
+ $Sqrt(4); -- 2
+
+SELECT
+ AGGREGATE_BY(x, $Agg_sum), -- 5
+ AGGREGATE_BY(x, $Agg_max) -- 3
+FROM (
+ SELECT 2 AS x
+ UNION ALL
+ SELECT 3 AS x
+)
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/as.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/as.md
new file mode 100644
index 00000000000..4da92fdd1fe
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/as.md
@@ -0,0 +1,44 @@
+## AS {#as}
+
+Can be used in the following scenarios:
+
+* Adding a short name (alias) for columns or tables within the query.
+* Using named arguments in function calls.
+* To specify the target type in the case of explicit type casting, see [CAST](#cast).
+
+{% if select_command != "SELECT STREAM" %}
+**Examples:**
+
+```yql
+SELECT key AS k FROM my_table;
+```
+
+```yql
+SELECT t.key FROM my_table AS t;
+```
+
+```yql
+SELECT
+ MyFunction(key, 123 AS my_optional_arg)
+FROM my_table;
+```
+
+{% else %}
+**Examples:**
+
+```yql
+SELECT STREAM key AS k FROM my_stream;
+```
+
+```yql
+SELECT STREAM s.key FROM my_stream AS s;
+```
+
+```yql
+SELECT STREAM
+ MyFunction(key, 123 AS my_optional_arg)
+FROM my_stream;
+```
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/between.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/between.md
new file mode 100644
index 00000000000..e1f3edfeb51
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/between.md
@@ -0,0 +1,11 @@
+## BETWEEN {#between}
+
+Checking whether a value is in a range. It's equivalent to two conditions with `>=` and `<=` (range boundaries are included). Can be used with the `NOT` prefix to support inversion.
+
+**Examples**
+
+```yql
+SELECT * FROM my_table
+WHERE key BETWEEN 10 AND 20;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/bitcast.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/bitcast.md
new file mode 100644
index 00000000000..064bcb9a328
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/bitcast.md
@@ -0,0 +1,15 @@
+## BITCAST {#bitcast}
+
+Performs a bitwise conversion of an integer value to the specified integer type. The conversion is always successful, but may lose precision or high-order bits.
+
+**Examples**
+
+```yql
+SELECT
+ BITCAST(100000ul AS Uint32), -- 100000
+ BITCAST(100000ul AS Int16), -- -31072
+ BITCAST(100000ul AS Uint16), -- 34464
+ BITCAST(-1 AS Int16), -- -1
+ BITCAST(-1 AS Uint16); -- 65535
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/case.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/case.md
new file mode 100644
index 00000000000..50ee8fd8cdf
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/case.md
@@ -0,0 +1,30 @@
+## CASE{#case}.
+
+Conditional expressions and branching. It's similar to `if`, `switch` and ternary operators in the imperative programming languages.
+If the result of the `WHEN` expression is `true`, the value of the `CASE` expression becomes the result following the condition, and the rest of the `CASE` expression isn't calculated. If the condition is not met, all the `WHEN` clauses that follow are checked. If none of the `WHEN` clauses are met, the `CASE` value is assigned the result from the `ELSE` clause.
+The `ELSE` branch is mandatory in the `CASE` expression. Expressions in `WHEN` are checked sequentially, from top to bottom.
+
+Since its syntax is quite sophisticated, it's often more convenient to use the built-in function [IF](../../../builtins/basic.md#if).
+
+**Examples**
+
+```yql
+SELECT
+ CASE
+ WHEN value > 0
+ THEN "positive"
+ ELSE "negative"
+ END
+FROM my_table;
+```
+
+```yql
+SELECT
+ CASE value
+ WHEN 0 THEN "zero"
+ WHEN 1 THEN "one"
+ ELSE "not zero or one"
+ END
+FROM my_table;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/cast.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/cast.md
new file mode 100644
index 00000000000..9820614f919
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/cast.md
@@ -0,0 +1,15 @@
+## CAST {#cast}
+
+Tries to cast the value to the specified type. The attempt may fail and return `NULL`. When used with numbers, it may lose precision or most significant bits.
+{% if feature_column_container_type %}
+For lists and dictionaries, it can either delete or replace with `NULL` the elements whose conversion failed.
+For structures and tuples, it deletes elements that are omitted in the target type.
+For more information about casting rules, see [here](../../../types/cast.md).
+{% endif %}
+
+{% include [decimal_args](../../../_includes/decimal_args.md) %}
+
+**Examples**
+
+{% include [cast_examples](../../../_includes/cast_examples.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/check-match.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/check-match.md
new file mode 100644
index 00000000000..864acf68902
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/check-match.md
@@ -0,0 +1,45 @@
+## Matching a string by pattern {#check-match}
+
+`REGEXP` and `RLIKE` are aliases used to call [Hyperscan::Grep](../../../udf/list/hyperscan.md#grep). `MATCH`: Same for [Hyperscan::Match](../../../udf/list/hyperscan.md#match).
+
+`LIKE` works as follows:
+
+* Patterns can include two special characters:
+ * `%`: Zero or more of any characters.
+ * `_`: Exactly one of any character.
+All other characters are literals that represent themselves.
+* As opposed to `REGEXP`, `LIKE` must be matched exactly. For example, to search a substring, add `%` at the beginning and end of the pattern.
+* `ILIKE` is a case-insensitive version of `LIKE`.
+* If `LIKE` is applied to the key column of the sorted table and the pattern doesn't start with a special character, filtering by prefix drills down directly to the cluster level, which in some cases lets you avoid the full table scan. This optimization is disabled for `ILIKE`.
+* To escape special characters, specify the escaped character after the pattern using the `ESCAPE '?'` keyword. Instead of `?` you can use any character except `%` and `_`. For example, if you use a question mark as an escape character, the expressions `?%`, `?_` and `??` will match their second character in the template: percent, underscore, and question mark, respectively. The escape character is undefined by default.
+
+The most popular way to use the `LIKE` and `REGEXP` keywords is to filter a table using the statements with the `WHERE` clause. However, there are no restrictions on using templates in this context: you can use them in most of contexts involving strings, for example, with concatenation by using `||`.
+
+**Examples**
+
+```yql
+SELECT * FROM my_table
+WHERE string_column REGEXP '\\d+';
+-- the second slash is required because
+-- all the standard string literals in SQL
+-- can accept C-escaped strings
+```
+
+```yql
+SELECT
+ string_column LIKE '___!_!_!_!!!!!!' ESCAPE '!'
+ -- searches for a string of exactly 9 characters:
+ -- 3 arbitrary characters
+ -- followed by 3 underscores
+ -- and 3 exclamation marks
+FROM my_table;
+```
+
+```yql
+SELECT * FROM my_table
+WHERE key LIKE 'foo%bar';
+-- would probably only physically scan the keys
+-- starting with "foo", and then, among them,
+-- will leave only those that end in "bar"
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/concatenation.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/concatenation.md
new file mode 100644
index 00000000000..bf771376278
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/concatenation.md
@@ -0,0 +1,14 @@
+## String concatenation {#concatenation}
+
+Executed using the binary operator `||`.
+
+As with other binary operators, if the data on either side is `NULL`, the result is also `NULL`.
+
+Don't confuse this operator with a logical "or": in SQL, it's denoted by the `OR` keyword. It's also not worth doing concatenation using `+`.
+
+**Examples**
+
+```sql
+SELECT "fo" || "o";
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/in.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/in.md
new file mode 100644
index 00000000000..1c124f58379
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/in.md
@@ -0,0 +1,45 @@
+## IN {#in}
+
+Checking whether a value is inside of a set of values. It's logically equivalent to a chain of equality comparisons using `OR` but implemented more efficiently.
+
+{% note warning "Warning" %}
+
+Unlike a similar keyword in Python, in YQL `IN ` **DOES NOT** searches for a substring inside a string. To search for a substring, use the function [String::Contains](../../../udf/list/string.md) or [LIKE/REGEXP](#like) mentioned above.
+
+{% endnote %}
+
+Immediately after `IN`, you can specify the `COMPACT` hint.
+If `COMPACT` is not specified, then `IN` with a subquery is executed as a relevant `JOIN` (`LEFT SEMI` for `IN` and `LEFT ONLY` for `NOT IN`), if possible.
+Using the `COMPACT` hint forces the in-memory execution strategy: a hash table is immediately built from the contents of the right `IN` part in-memory, and then the left part is filtered.
+
+The `COMPACT` hint must be used with care. Since the hash table is built in-memory, the query may fail if the right part of `IN` contains many large or different elements.
+
+{% if feature_mapreduce %} Since YQL imposes a limit on the query size in bytes (it's about 1Mb), add large lists of values to your query by URLs and use the [ParseFile](../../../builtins/basic.md#parsefile) function.
+{% endif %}
+
+**Examples**
+
+```yql
+SELECT column IN (1, 2, 3)
+FROM my_table;
+```
+
+```yql
+SELECT * FROM my_table
+WHERE string_column IN ("a", "b", "c");
+```
+
+```yql
+$foo = AsList(1, 2, 3);
+SELECT 1 IN $foo;
+```
+
+```yql
+$values = (SELECT column + 1 FROM table);
+SELECT * FROM my_table WHERE
+ -- filtering by an in-memory hash table for one_table
+ column1 IN COMPACT $values AND
+ -- followed by LEFT ONLY JOIN with other_table
+ column2 NOT IN (SELECT other_column FROM other_table);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/is-distinct-from.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/is-distinct-from.md
new file mode 100644
index 00000000000..c54862cef21
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/is-distinct-from.md
@@ -0,0 +1,13 @@
+## IS \[NOT\] DISTINCT FROM {#is-distinct-from}
+
+Comparing of two values. Unlike the regular [comparison operators](#comparison-operators), NULLs are treated as equal to each other.
+More precisely, the comparison is carried out according to the following rules:
+
+1) The operators `IS DISTINCT FROM`/`IS NOT DISTINCT FROM` are defined for those and only for those arguments for which the operators `!=` and `=` are defined.
+2) The result of `IS NOT DISTINCT FROM` is equal to the logical negation of the `IS DISTINCT FROM` result for these arguments.
+3) If the result of the `==` operator is not equal to zero for some arguments, then it is equal to the result of the `IS NOT DISTINCT FROM` operator for the same arguments.
+4) If both arguments are empty `Optional` or `NULL`s, then the value of `IS NOT DISTINCT FROM` is `True`.
+5) The result of `IS NOT DISTINCT FROM` for an empty `Optional` or `NULL` and filled-in `Optional` or non-`Optional` value is `False`.
+
+For values of composite types, these rules are used recursively.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/is-null.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/is-null.md
new file mode 100644
index 00000000000..f8242bf2f42
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/is-null.md
@@ -0,0 +1,11 @@
+## IS \[NOT\] NULL {#is-null}
+
+Matching an empty value (`NULL`). Since `NULL` is a special value [equal to nothing](../../../types/optional.md#null_expr), the ordinary [comparison operators](#comparison-operators) can't be used to match it.
+
+**Examples**
+
+```yql
+SELECT key FROM my_table
+WHERE value IS NOT NULL;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/items-access.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/items-access.md
new file mode 100644
index 00000000000..6f4c1d2ad30
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/items-access.md
@@ -0,0 +1,27 @@
+## Accessing containers {#items-access}
+
+For accessing the values inside containers:
+
+* `Struct<>`, `Tuple<>` and `Variant<>`, use a **dot**. The set of keys (for the tuple and the corresponding variant — indexes) is known at the query compilation time. The key is **validated** before beginning the query execution.
+* `List<>` and `Dict<>`, use **square brackets**. The set of keys (set of indexes for keys) is known only at the query execution time. The key is **not validated** before beginning the query execution. If no value is found, an empty value (NULL) is returned.
+
+[Description and list of available containers](../../../types/containers.md).
+
+When using this syntax to access containers within table columns, be sure to specify the full column name, including the table name or table alias separated by a dot (see the first example below).
+
+**Examples**
+
+```yql
+SELECT
+ t.struct.member,
+ t.tuple.7,
+ t.dict["key"],
+ t.list[7]
+FROM my_table AS t;
+```
+
+```yql
+SELECT
+ Sample::ReturnsStruct().member;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/lambda.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/lambda.md
new file mode 100644
index 00000000000..bb4d8367257
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/lambda.md
@@ -0,0 +1,33 @@
+## Lambda functions {#lambda}
+
+Let you combine multiple expressions into a single callable value.
+
+List arguments in round brackets, following them by the arrow and lambda function body. The lambda function body includes either an expression in round brackets or curly brackets around an optional chain of [named expressions](#named-nodes) assignments and the call result after the `RETURN` keyword in the last expression.
+
+The scope for the lambda body: first the local named expressions, then arguments, then named expressions defined above by the lambda function at the top level of the query.
+
+Only use pure expressions inside the lambda body (those might also be other lambdas, possibly passed through arguments). However, you can't use [SELECT](../../select.md), [INSERT INTO](../../insert_into.md), or other top-level expressions.
+
+One or more of the last lambda parameters can be marked with a question mark as optional: if they haven't been specified when calling lambda, they are assigned the `NULL` value.
+
+**Examples**
+
+```yql
+$f = ($y) -> {
+ $prefix = "x";
+ RETURN $prefix || $y;
+};
+
+$g = ($y) -> ("x" || $y);
+
+$h = ($x, $y?) -> ($x + ($y ?? 0));
+
+SELECT $f("y"), $g("z"), $h(1), $h(2, 3); -- "xy", "xz", 1, 5
+```
+
+```yql
+-- if the lambda result is calculated by a single expression, then you can use a more compact syntax:
+$f = ($x, $_) -> ($x || "suffix"); -- the second argument is not used
+SELECT $f("prefix_", "whatever");
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/named-nodes.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/named-nodes.md
new file mode 100644
index 00000000000..ba6bf4df04d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/named-nodes.md
@@ -0,0 +1,93 @@
+## Named expressions {#named-nodes}
+
+Complex queries may be sophisticated, containing lots of nested levels and/or repeating parts. In YQL, you can use named expressions to assign a name to an arbitrary expression or subquery. Named expressions can be referenced in other expressions or subqueries. In this case, the original expression/subquery is actually substituted at point of use.
+
+A named expression is defined as follows:
+
+```
+<named-expr> = <expression> | <subquery>;
+```
+
+Here `<named-expr>` consists of a $ character and an arbitrary non-empty identifier (for example, `$foo`).
+
+If the expression on the right is a tuple, you can automatically unpack it by specifying several named expressions separated by commas on the left:
+
+```
+<named-expr1>, <named-expr2>, <named-expr3> ... = <expression-returning-tuple>;
+```
+
+In this case, the number of expressions must match the tuple size.
+
+Each named expression has a scope. It starts immediately after the definition of a named expression and ends at the end of the nearest enclosed namescope (for example, at the end of the query or at the end of the body of the [lambda function](#lambda), [ACTION](../../action.md#define-action){% if feature_subquery %}, [SUBQUERY](../../subquery.md#define-subquery){% endif %}{% if feature_mapreduce %}, or the cycle [EVALUATE FOR](../../action.md#evaluate-for){% endif %}).
+Redefining a named expression with the same name hides the previous expression from the current scope.
+
+If the named expression has never been used, a warning is issued. To avoid such a warning, use the underscore as the first character in the ID (for example, `$_foo`).
+The named expression `$_` is called an anonymous named expression and is processed in a special way: it works as if `$_` would be automatically replaced by `$_<some_uniq_name>`.
+Anonymous named expressions are convenient when you don't need the expression value. For example, to fetch the second element from a tuple of three elements, you can write:
+
+```yql
+$_, $second, $_ = AsTuple(1, 2, 3);
+select $second;
+```
+
+An attempt to reference an anonymous named expression results in an error:
+
+```yql
+$_ = 1;
+select $_; --- error: Unable to reference anonymous name $_
+export $_; --- An error: Can not export anonymous name $_
+```
+
+{% if feature_mapreduce %}
+Moreover, you can't import a named expression with an anonymous alias:
+
+```yql
+import utils symbols $sqrt as $_; --- error: Can not import anonymous name $_
+```
+
+{% endif %}
+Anonymous argument names are also supported for [lambda functions](#lambda), [ACTION](../../action.md#define-action){% if feature_subquery %}, [SUBQUERY](../../subquery.md#define-subquery){% endif %}{% if feature_mapreduce %}, and in [EVALUATE FOR](../../action.md#evaluate-for){% endif %}.
+
+{% note info %}
+
+If named expression substitution results in completely identical subgraphs in the query execution graph, the graphs are combined to execute a subgraph only once.
+
+{% endnote %}
+
+**Examples**
+
+```yql
+$multiplier = 712;
+SELECT
+ a * $multiplier, -- $multiplier is 712
+ b * $multiplier,
+ (a + b) * $multiplier
+FROM abc_table;
+$multiplier = c;
+SELECT
+ a * $multiplier -- $multiplier is column c
+FROM abc_table;
+```
+
+```yql
+$intermediate = (
+ SELECT
+ value * value AS square,
+ value
+ FROM my_table
+);
+SELECT a.square * b.value
+FROM $intermediate AS a
+INNER JOIN $intermediate AS b
+ON a.value == b.square;
+```
+
+```yql
+$a, $_, $c = AsTuple(1, 5u, "test"); -- unpack a tuple
+SELECT $a, $c;
+```
+
+```yql
+$x, $y = AsTuple($y, $x); -- swap expression values
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/operators.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/operators.md
new file mode 100644
index 00000000000..36f06850552
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/operators.md
@@ -0,0 +1,87 @@
+## Operators
+
+### Arithmetic operators {#math-operators}
+
+The operators `+`, `-`, `*`, `/`, `%` are defined for [primitive data types](../../../types/primitive.md) that are variations of numbers.
+
+For the Decimal data type, bankers rounding is used (to the nearest even integer).
+
+**Examples**
+
+```yql
+SELECT 2 + 2;
+```
+
+```yql
+SELECT 0.0 / 0.0;
+```
+
+### Comparison operators {#comparison-operators}
+
+The operators `=`, `==`, `!=`, `<>`, `>`, `<` are defined for:
+
+* Primitive data types except Yson and Json.
+* Tuples and structures with the same set of fields. No order is defined for structures, but you can check for (non-)equality. Tuples are compared element-by-element left to right.
+
+**Examples**
+
+```yql
+SELECT 2 > 1;
+```
+
+### Logical operators {#logic-operators}
+
+Use the operators `AND`, `OR`, `XOR` for logical operations on Boolean values (`Bool`).
+
+**Examples**
+
+```yql
+SELECT 3 > 0 AND false;
+```
+
+### Bitwise operators {#bit-operators}
+
+Bitwise operations on numbers:
+
+* `&`, `|`, `^`: AND, OR, and XOR, respectively. Don't confuse bitwise operations with the related keywords. The keywords `AND`, `OR`, and `XOR` are used * for Boolean values only*, but not for numbers.
+* ` ~ `: A negation.
+* `<`, `>`: Left or right shifts.
+* `|<`, `>|`: Circular left or right shifts.
+
+**Examples**
+
+```yql
+SELECT
+ key << 10 AS key,
+ ~value AS value
+FROM my_table;
+```
+
+### Precedence and associativity of operators {#operator-priority}
+
+Operator precedence determines the order of evaluation of an expression that contains different operators.
+For example, the expression `1 + 2 * 3` is evaluated as `1 + (2 * 3)` because the multiplication operator has a higher precedence than the addition operator.
+
+Associativity determines the order of evaluating expressions containing operators of the same type.
+For example, the expression `1 + 2 + 3` is evaluated as `(1 + 2) + 3` because the addition operator is left-associative.
+On the other hand, the expression `a ?? b ?? c` is evaluated as `a ?? (b ?? c)` because the `??` operator is right-associative
+
+The table below shows precedence and associativity of YQL operators.
+The operators in the table are listed in descending order of precedence.
+
+| Priority | Operator | Description | Associativity |
+| --- | --- | --- | --- |
+| 1 | <code>a[], a.foo, a()</code> | Accessing a container item, calling a function | Left |
+| 2 | <code>+a, -a, ~a, NOT a</code> | Unary operators: plus, minus, bitwise and logical negation | Right |
+| 3 | <code>a &#124;&#124; b</code> | [String concatenation](#concatenation) | Left |
+| 4 | <code>a*b, a/b, a%b</code> | Multiplication, division, remainder of division | Left |
+| 5 | <code>a+b, a-b</code> | Addition/Subtraction | Left |
+| 6 | <code>a ?? b</code> | Operator notation for [NVL/COALESCE](../../../builtins/basic.md#coalesce) | Right |
+| 7 | <code>a<b, a>b, a&#124;<b, a>&#124;b,</code> <code>a&#124;b, a^b, a&b</code> | Shift operators and logical bit operators | Left |
+| 8 | <code>a<b, a=b, a=b, a>b</code> | Comparison | Left |
+| 9 | <code>a IN b</code> | Occurrence of an element in a set | Left |
+| 9 | <code>a==b, a=b, a!=b, a<>b,</code> <code>a is (not) distinct from b</code> | Comparison for (non-)equality | Left |
+| 10 | <code>a XOR b</code> | Logical XOR | Left |
+| 11 | <code>a AND b</code> | Logical AND | Left |
+| 12 | <code>a OR b</code> | Logical OR | Left |
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/tables.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/tables.md
new file mode 100644
index 00000000000..cb6e91aa272
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/expressions/tables.md
@@ -0,0 +1,71 @@
+## Table expressions {#table-contexts}
+
+A table expression is an expression that returns a table. Table expressions in YQL are as follows:
+
+* Subqueries: `(SELECT key, subkey FROM T)`
+* [Named subqueries](#named-nodes): `$foo = SELECT * FROM T;` (in this case, `$foo` is also a table expression)
+{% if feature_subquery %}
+* [Subquery templates](../../subquery.md#define-subquery): `DEFINE SUBQUERY $foo($name) AS ... END DEFINE;` (`$foo("InputTable")` is a table expression).
+{% endif %}
+
+Semantics of a table expression depends on the context where it is used. In YQL, table expressions can be used in the following contexts:
+
+* Table context: after [FROM](../../select.md#from).
+In this case, table expressions work as expected: for example, `$input = SELECT a, b, c FROM T; SELECT * FROM $input` returns a table with three columns.
+The table context also occurs after [UNION ALL](../../select.md#unionall){% if feature_join %}, [JOIN](../../join.md#join){% endif %}{% if feature_mapreduce and process_command == "PROCESS" %}, [PROCESS](../../process.md#process), [REDUCE](../../reduce.md#reduce){% endif %};
+* Vector context: after [IN](#in). In this context, the table expression must contain exactly one column (the name of this column doesn't affect the expression result in any way).
+A table expression in a vector context is typed as a list (the type of the list element is the same as the column type in this case). Example: `SELECT * FROM T WHERE key IN (SELECT k FROM T1)`;
+* A scalar context arises _in all the other cases_. As in a vector context, a table expression must contain exactly one column, but the value of the table expression is a scalar, that is, an arbitrarily selected value of this column (if no rows are returned, the result is `NULL`). Example: `$count = SELECT COUNT(*) FROM T; SELECT * FROM T ORDER BY key LIMIT $count / 2`;
+
+The order of rows in a table context, the order of elements in a vector context, and the rule for selecting a value from a scalar context (if multiple values are returned), aren't defined. This order also cannot be affected by `ORDER BY`: `ORDER BY` without `LIMIT` is ignored in table expressions with a warning, and `ORDER BY` with `LIMIT` defines a set of elements rather than the order within that set.
+
+{% if feature_mapreduce and process_command == "PROCESS" %}
+
+There is an exception to this rule. Named expression with [PROCESS](../../process.md#process), if used in a scalar context, behaves as in a table context:
+
+```yql
+$input = SELECT 1 AS key, 2 AS value;
+$process = PROCESS $input;
+
+SELECT FormatType(TypeOf($process)); -- $process is used in a scalar context,
+ -- but the SELECT result in this case is List<Struct'key':Int32,'value':Int32>
+
+SELECT $process[0].key; -- that returns 1
+
+SELECT FormatType(TypeOf($input)); -- throws an error: $input in a scalar context must contain one column
+```
+
+{% note warning "Warning" %}
+
+A common error is to use an expression in a scalar context rather than a table context or vector context. For example:
+
+```yql
+$dict = SELECT key, value FROM T1;
+
+DEFINE SUBQUERY $merge_dict($table, $dict) AS
+SELECT * FROM $table LEFT JOIN $dict USING(key);
+END DEFINE;
+
+SELECT * FROM $merge_dict("Input", $dict); -- $dict is used in a scalar context in this case.
+ -- an error: exactly one column is expected in a scalar context
+```
+
+A correct notation in this case is:
+
+```yql
+DEFINE SUBQUERY $dict() AS
+SELECT key, value FROM T1;
+END DEFINE;
+
+DEFINE SUBQUERY $merge_dict($table, $dict) AS
+SELECT * FROM $table LEFT JOIN $dict() USING(key); -- Using the table expression $dict()
+ -- (Calling a subquery template) in a table context
+END DEFINE;
+
+SELECT * FROM $merge_dict("Input", $dict); -- $dict - is a subquery template (rather than a table expression)
+ -- that is passed as an argument of a table expression
+```
+
+{% endnote %}
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_by.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_by.md
new file mode 100644
index 00000000000..d12d8463293
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_by.md
@@ -0,0 +1,71 @@
+# FLATTEN
+
+## FLATTEN BY {#flatten-by}
+
+Converts rows in the source table using vertical unpacking of [containers](../../../types/containers.md) of variable length (lists or dictionaries).
+
+For example:
+
+* Source table:
+ |[a, b, c]|1|
+ | --- | --- |
+ |[d]|2|
+ |[]|3|
+
+* The table resulting from `FLATTEN BY` on the left column:
+ |a|1|
+ | --- | --- |
+ |b|1|
+ |c|1|
+ |d|2|
+
+{% if feature_column_container_type != true %}
+
+{{ backend_name }} tables don't support container types, so the FLATTEN BY function can only be applied to table-type variables created within a YQL query.
+
+{% endif %}
+
+**Example**
+
+```(sql)
+$sample = AsList(
+ AsStruct(AsList('a','b','c') AS value, CAST(1 AS Uint32) AS id),
+ AsStruct(AsList('d') AS value, CAST(2 AS Uint32) AS id),
+ AsStruct(AsList() AS value, CAST(3 AS Uint32) AS id)
+);
+
+SELECT value, id FROM as_table($sample) FLATTEN BY (value);
+```
+
+This conversion can be convenient in the following cases:
+
+* When it is necessary to output statistics by cells from a container column (for example, via [`GROUP BY`](../../group_by.md)).
+{% if feature_join %}
+* When the cells in a container column store IDs from another table that you want to join with [`JOIN`](../../join.md).
+{% endif %}
+
+**Syntax**
+
+* `FLATTEN BY` is specified after `FROM`, but before `GROUP BY`, if `GROUP BY` is present in the query.
+* The type of the result column depends on the type of the source column:
+
+| Container type | Result type | Comments |
+| --- | --- | --- |
+| `List<X>` | `X` | List cell type |
+| `Dict<X,Y>` | `Tuple<X,Y>` | Tuple of two elements containing key-value pairs |
+| `Optional<X>` | `X` | The result is almost equivalent to the clause `WHERE foo IS NOT NULL`, but the `foo` column type is changed to `X` |
+
+* By default, the result column replaces the source column. Use `FLATTEN BY foo AS bar` to keep the source container. As a result, the source container is still available as `foo` and the output container is available as `bar`.
+* To build a Cartesian product of multiple container columns, use the clause `FLATTEN BY (a, b, c)`. Parentheses are mandatory to avoid grammar conflicts.
+* Inside `FLATTEN BY`, you can only use column names from the input table. To apply `FLATTEN BY` to the calculation result, use a subquery.
+* In `FLATTEN BY ` you can use both columns and arbitrary named expressions (unlike columns, `AS` is required in this case). To avoid grammatical ambiguities of the expression after `FLATTEN BY`, make sure to use parentheses with the following: `... FLATTEN BY (ListSkip(col, 1) AS col) ...`
+* If the source column had nested containers, for example, `List<DictX,Y>`, `FLATTEN BY` unpacks only the outer level. To completely unpack the nested containers, use a subquery.
+
+{% note info %}
+
+`FLATTEN BY` interprets [optional data types](../../../types/optional.md) as lists of length 0 or 1. The table rows with `NULL` are skipped, and the column type changes to a similar non-optional type.
+
+`FLATTEN BY` makes only one conversion at a time, so use `FLATTEN LIST BY` or `FLATTEN OPTIONAL BY` on optional containers, for example, `Optional<List<String>>`.
+
+{% endnote %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_columns.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_columns.md
new file mode 100644
index 00000000000..b9ce21c63df
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_columns.md
@@ -0,0 +1,20 @@
+## FLATTEN COLUMNS {#flatten-columns}
+
+Converts a table where all columns must be structures to a table with columns corresponding to each element of each structure from the source columns.
+
+The names of the source column structures are not used and not returned in the result. Be sure that the structure element names aren't repeated in the source columns.
+
+**Example**
+
+```sql
+SELECT x, y, z
+FROM (
+ SELECT
+ AsStruct(
+ 1 AS x,
+ "foo" AS y),
+ AsStruct(
+ false AS z)
+) FLATTEN COLUMNS;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_other_db.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_other_db.md
new file mode 100644
index 00000000000..3692fe89ef4
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_other_db.md
@@ -0,0 +1,8 @@
+### Analogs of FLATTEN BY in other DBMS {#flatten-other-dmb}
+
+* PostgreSQL: `unnest`
+* Hive: `LATERAL VIEW`
+* MongoDB: `unwind`
+* Google BigQuery: `FLATTEN`
+* ClickHouse: `ARRAY JOIN / arrayJoin`
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_type_by.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_type_by.md
new file mode 100644
index 00000000000..0f4c5e5bea5
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_type_by.md
@@ -0,0 +1,44 @@
+### Specifying the container type {#flatten-by-specific-type}
+
+To specify the type of container to convert to, you can use:
+
+* `FLATTEN LIST BY`
+
+ For `Optional<List<T>>`, `FLATTEN LIST BY` will unpack the list, treating `NULL` as an empty list.
+
+* `FLATTEN DICT BY`
+
+ For `Optional<Dict<T>>`, `FLATTEN DICT BY` will unpack the dictionary, interpreting `NULL` as an empty dictionary.
+
+* `FLATTEN OPTIONAL BY`
+
+ To filter the `NULL` values without serialization, specify the operation by using `FLATTEN OPTIONAL BY`.
+
+**Examples**
+
+```sql
+SELECT
+ t.item.0 AS key,
+ t.item.1 AS value,
+ t.dict_column AS original_dict,
+ t.other_column AS other
+FROM my_table AS t
+FLATTEN DICT BY dict_column AS item;
+```
+
+```sql
+SELECT * FROM (
+ SELECT
+ AsList(1, 2, 3) AS a,
+ AsList("x", "y", "z") AS b
+) FLATTEN LIST BY (a, b);
+```
+
+```yql
+SELECT * FROM (
+ SELECT
+ "1;2;3" AS a,
+ AsList("x", "y", "z") AS b
+) FLATTEN LIST BY (String::SplitToList(a, ";") as a, b);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md
new file mode 100644
index 00000000000..99bad56ad97
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md
@@ -0,0 +1,18 @@
+## GROUP COMPACT BY
+
+Improves aggregation efficiency if the query author knows in advance that none of aggregation keys finds large amounts of data (i.e., with the order of magnitude exceeding a gigabyte or a million of rows). If this assumption fails to materialize, then the operation may fail with Out of Memory error or start running much slower compared to the non-COMPACT version.
+
+Unlike the usual GROUP BY, the Map-side combiner stage and additional Reduce are disabled for each field with [DISTINCT](#distinct) aggregation.
+
+**Example:**
+
+```yql
+SELECT
+ key,
+ COUNT (DISTINCT value) AS count -- top 3 keys by the number of unique values
+FROM my_table
+GROUP COMPACT BY key
+ORDER BY count DESC
+LIMIT 3;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/distinct.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/distinct.md
new file mode 100644
index 00000000000..9070a7cb229
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/distinct.md
@@ -0,0 +1,24 @@
+## DISTINCT {#distinct}
+
+Applying [aggregate functions](../../../builtins/aggregation.md) only to distinct values of the column.
+
+{% note info %}
+
+Applying `DISTINCT` to calculated values is not currently implemented. For this purpose, you can use a [subquery](../../select.md#from) or the expression `GROUP BY ... AS ...`.
+
+{% endnote %}
+
+**Example**
+
+```sql
+SELECT
+ key,
+ COUNT (DISTINCT value) AS count -- top 3 keys by the number of unique values
+FROM my_table
+GROUP BY key
+ORDER BY count DESC
+LIMIT 3;
+```
+
+You can also use `DISTINCT` to fetch distinct rows using [`SELECT DISTINCT`](../../select.md#distinct).
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/general.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/general.md
new file mode 100644
index 00000000000..b951a443006
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/general.md
@@ -0,0 +1,66 @@
+## GROUP BY
+
+Group the `SELECT` results by the values of the specified columns or expressions. `GROUP BY` is often combined with [aggregate functions](../../../builtins/aggregation.md) (`COUNT`, `MAX`, `MIN`, `SUM`, `AVG`) to perform calculations in each group.
+
+**Syntax**
+
+```sql
+SELECT -- In SELECT, you can use:
+ column1, -- key columns specified in GROUP BY
+ key_n, -- named expressions specified in GROUP BY
+ column1 + key_n, -- arbitrary non-aggregate functions on them
+ Aggr_Func1( column2 ), -- aggregate functions containing any columns as arguments,
+ Aggr_Func2( key_n + column2 ), -- including named expressions specified in GROUP BY
+ ...
+FROM table
+GROUP BY
+ column1, column2, ...,
+ <expr> AS key_n -- When grouping by expression, you can set a name for it using AS,
+ -- and use it in SELECT
+```
+
+The query in the format `SELECT * FROM table GROUP BY k1, k2, ...` returns all columns listed in GROUP BY, i.e., is equivalent to `SELECT DISTINCT k1, k2, ... FROM table`.
+
+An asterisk can also be used as an argument for the `COUNT` aggregate function. `COUNT(*)` means "the count of rows in the group".
+
+{% note info %}
+
+Aggregate functions ignore `NULL` in their arguments, except for `COUNT`.
+
+{% endnote %}
+
+YQL also provides aggregation factories implemented by the functions [`AGGREGATION_FACTORY`](../../../builtins/basic.md#aggregationfactory) and [`AGGREGATE_BY`](../../../builtins/aggregation.md#aggregateby).
+
+**Examples**
+
+```sql
+SELECT key, COUNT(*) FROM my_table
+GROUP BY key;
+```
+
+```sql
+SELECT double_key, COUNT(*) FROM my_table
+GROUP BY key + key AS double_key;
+```
+
+```sql
+SELECT
+ double_key, -- OK: A key column
+ COUNT(*) AS group_size, -- OK: COUNT(*)
+ SUM(key + subkey) AS sum1, -- OK: An aggregate function
+ CAST(SUM(1 + 2) AS String) AS sum2, -- OK: An aggregate function with a constant argument
+ SUM(SUM(1) + key) AS sum3, -- ERROR: Nested aggregations are not allowed
+ key AS k1, -- ERROR: Using a non-key column named key without aggregation
+ key * 2 AS dk1, -- ERROR in YQL: using a non-key column named key without aggregation
+FROM my_table
+GROUP BY
+ key * 2 AS double_key,
+ subkey as sk,
+```
+
+{% note warning %}
+
+Specifying a name for a column or expression in `GROUP BY .. AS foo` it is an extension on top of YQL. Such a name becomes visible in `WHERE` despite the fact that filtering by `WHERE` is executed [before](../../select.md#selectexec) the grouping. For example, if the `T` table includes two columns, `foo` and `bar`, then the query `SELECT foo FROM T WHERE foo > 0 GROUP BY bar AS foo` would actually filter data by the `bar` column from the source table.
+
+{% endnote %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/general_stream.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/general_stream.md
new file mode 100644
index 00000000000..4514e14280e
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/general_stream.md
@@ -0,0 +1,59 @@
+## GROUP BY ... HOP
+
+Group the table by the values of the specified columns or expressions and the time window.
+
+If GROUP BY is present in the query, then when selecting columns (between `SELECT STREAM ... FROM`) you can **only** use the following constructs:
+
+1. Columns by which grouping is performed (they are included in the `GROUP BY` argument).
+2. Aggregate functions (see the next section). Columns by which **no** grouping is made can only be included as arguments for an aggregate function.
+3. Functions that output the start and end time of the current window (`HOP_START` and `HOP_END`)
+4. Arbitrary calculations combining paragraphs 1-3.
+
+You can group by the result of calculating an arbitrary expression from the source columns. In this case, to access the result of this expression, we recommend you to assign a name to it using `AS`, see the second example.
+
+Aggregate functions automatically skip `NULL` in their arguments.
+
+Among the columns by which grouping is performed, make sure to use the `HOP` construct to define the time window for grouping.
+
+```yql
+HOP(time_extractor, hop, interval, delay)
+```
+
+The implemented version of the time window is called the **hopping window**. This is a window that moves forward in discrete intervals (the `hop` parameter). The total duration of the window is set by the `interval` parameter. To determine the time of each input event, the `time_extractor` parameter is used. This expression depends only on the input values of the stream's columns and must have the `Timestamp` type. It indicates where exactly to get the time value from input events.
+
+In each stream defined by the values of all the grouping columns, the window moves forward independently of other streams. Advancement of the window is totally dependent on the latest event of the stream. Since records in streams get somewhat mixed in time, the `delay` parameter has been added so you can delay the closing of the window by a specified period. Events arriving before the current window are ignored.
+
+The `interval` and `delay` parameters must be multiples of the `hop` parameter. Non-multiple intervals will be rounded down.
+
+To set `hop`, `interval` and `delay`, use a string expression compliant with [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). This is the format that is used to construct the built-in type `Interval` [from a string](../../../builtins/basic.md#data-type-literals).
+
+Functions with omitted `HOP_START` and `HOP_END` parameters, return a value of the `Timestamp` type and correspond to the start and end of the current window.
+
+The **tumbling window** known in other systems is a special case of a **hopping window** when `interval` == `hop`.
+
+**Examples:**
+
+```yql
+SELECT STREAM
+ key,
+ COUNT(*)
+FROM my_stream
+GROUP BY
+ HOP(CAST(subkey AS Timestamp), "PT10S", "PT1M", "PT30S"),
+ key;
+-- hop = 10 seconds
+-- interval = 1 minute
+-- delay = 30 seconds
+```
+
+```yql
+SELECT STREAM
+ double_key,
+ HOP_END() as time,
+ COUNT(*) as count
+FROM my_stream
+GROUP BY
+ key + key AS double_key,
+ HOP(ts, "PT1M", "PT1M", "PT1M");
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/having.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/having.md
new file mode 100644
index 00000000000..5eca8c31715
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/having.md
@@ -0,0 +1,14 @@
+## HAVING {#having}
+
+Filtering a `SELECT` based on the calculation results of [aggregate functions](../../../builtins/aggregation.md). The syntax is similar to [WHERE](../../select.md#where).
+
+**Example**
+
+```yql
+SELECT
+ key
+FROM my_table
+GROUP BY key
+HAVING COUNT(value) > 100;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/having_stream.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/having_stream.md
new file mode 100644
index 00000000000..a73539ba749
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/having_stream.md
@@ -0,0 +1,14 @@
+## HAVING {#having}
+
+Filtering a `SELECT STREAM` based on the calculation results of [aggregate functions](../../../builtins/aggregation.md). The syntax is similar to [WHERE](../../select_stream.md#where).
+
+**Examples:**
+
+```yql
+SELECT STREAM
+ key
+FROM my_table
+GROUP BY key, HOP(ts, "PT1M", "PT1M", "PT1M")
+HAVING COUNT(value) > 100;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/rollup_cube_sets.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/rollup_cube_sets.md
new file mode 100644
index 00000000000..d2c73fa0db2
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/rollup_cube_sets.md
@@ -0,0 +1,74 @@
+## ROLLUP, CUBE, and GROUPING SETS {#rollup}
+
+The results of calculating the aggregate function as subtotals for the groups and overall totals over individual columns or whole table.
+
+**Syntax**
+
+```sql
+SELECT
+ c1, c2, -- the columns to group by
+
+AGGREGATE_FUNCTION(c3) AS outcome_c -- an aggregate function (SUM, AVG, MIN, MAX, COUNT)
+
+FROM table_name
+
+GROUP BY
+ GROUP_BY_EXTENSION(c1, c2) -- an extension of GROUP BY: ROLLUP, CUBE, or GROUPING SETS
+```
+
+* `ROLLUP` groups the column values in the order they are listed in the arguments (strictly from left to right), generates subtotals for each group and the overall total.
+* `CUBE` groups the values for every possible combination of columns, generates the subtotals for each group and the overall total.
+* `GROUPING SETS` sets the groups for subtotals.
+
+You can combine `ROLLUP`, `CUBE` and `GROUPING SETS`, separating them by commas.
+
+### GROUPING {#grouping}
+
+The values of columns not used in calculations are replaced with `NULL` in the subtotal. In the overall total, the values of all columns are replaced by `NULL`. `GROUPING`: A function that allows you to distinguish the source `NULL` values from the `NULL` values added while calculating subtotals and overall totals.
+
+`GROUPING` returns a bit mask:
+
+* `0`: If `NULL` is used for the original empty value.
+* `1`: If `NULL` is added for a subtotal or overall total.
+
+**Example**
+
+```sql
+SELECT
+ column1,
+ column2,
+ column3,
+
+ CASE GROUPING(
+ column1,
+ column2,
+ column3,
+ )
+ WHEN 1 THEN "Subtotal: column1 and column2"
+ WHEN 3 THEN "Subtotal: column1"
+ WHEN 4 THEN "Subtotal: column2 and column3"
+ WHEN 6 THEN "Subtotal: column3"
+ WHEN 7 THEN "Grand total"
+ ELSE "Individual group"
+ END AS subtotal,
+
+ COUNT(*) AS rows_count
+
+FROM my_table
+
+GROUP BY
+ ROLLUP(
+ column1,
+ column2,
+ column3
+ ),
+ GROUPING SETS(
+ (column2, column3),
+ (column3)
+ -- if you add here (column2) as well, then together
+ -- the ROLLUP and GROUPING SETS would produce a result
+ -- similar to CUBE
+ )
+;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/session_window.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/session_window.md
new file mode 100644
index 00000000000..60cdf5e6e97
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/group_by/session_window.md
@@ -0,0 +1,66 @@
+## GROUP BY ... SessionWindow() {#session-window}
+
+YQL supports grouping by session. To standard expressions in `GROUP BY`, you can add a special `SessionWindow` function:
+
+```sql
+SELECT
+ user,
+ session_start,
+ SessionStart() AS same_session_start, -- It's same as session_start
+ COUNT(*) AS session_size,
+ SUM(value) AS sum_over_session,
+FROM my_table
+GROUP BY user, SessionWindow(<time_expr>, <timeout_expr>) AS session_start
+```
+
+The following happens in this case:
+
+1) The input table is partitioned by the grouping keys specified in `GROUP BY`, ignoring SessionWindow (in this case, it's based on `user`).
+If `GROUP BY` includes nothing more than SessionWindow, then the input table gets into one partition.
+2) Each partition is split into disjoint subsets of rows (sessions).
+For this, the partition is sorted in the ascending order of the `time_expr` expression.
+The session limits are drawn between neighboring items of the partition, that differ in their `time_expr` values by more than `timeout_expr`.
+3) The sessions obtained in this way are the final partitions on which aggregate functions are calculated.
+
+The SessionWindow() key column (in the example, it's `session_start`) has the value "the minimum `time_expr` in the session".
+If `GROUP BY` includes SessionWindow(), you can use a special aggregate function
+[SessionStart](../../../builtins/aggregation.md#session-start).
+
+An extended version of SessionWindow with four arguments is also supported:
+
+`SessionWindow(<order_expr>, <init_lambda>, <update_lambda>, <calculate_lambda>)`
+
+Where:
+
+* `<order_expr>`: An expression used to sort the source partition
+* `<init_lambda>`: A lambda function to initialize the state of session calculation. It has the signature `(TableRow())->State`. It's called once for the first (following the sorting order) element of the source partition
+* `<update_lambda>`: A lambda function to update the status of session calculation and define the session limits. It has the signature `(TableRow(), State)->Tuple<Bool, State>`. It's called for every item of the source partition, except the first one. The new value of state is calculated based on the current row of the table and the previous state. If the first item in the return tuple is `True`, then a new session starts from the _current_ row. The key of the new session is obtained by applying `<calculate_lambda>` to the second item in the tuple.
+* `<calculate_lambda>`: A lambda function for calculating the session key (the "value" of SessionWindow() that is also accessible via SessionStart()). The function has the signature `(TableRow(), State)->SessionKey`. It's called for the first item in the partition (after `<init_lambda>`) and those items for which `<update_lambda>` has returned `True` in the first item in the tuple. Please note that to start a new session, you should make sure that `<calculate_lambda>` has returned a value different from the previous session key. Sessions having the same keys are not merged. For example, if `<calculate_lambda>` returns the sequence `0, 1, 0, 1`, then there will be four different sessions.
+
+Using the extended version of SessionWindow, you can, for example, do the following: divide a partition into sessions, as in the SessionWindow use case with two arguments, but with the maximum session length limited by a certain constant:
+
+**Example**
+
+```sql
+$max_len = 1000; is the maximum session length.
+$timeout = 100; is the timeout (timeout_expr in a simplified version of SessionWindow).
+
+$init = ($row) -> (AsTuple($row.ts, $row.ts)); is the session status: tuple from 1) value of the temporary column ts in the session's first line and 2) in the current line
+$update = ($row, $state) -> {
+ $is_end_session = $row.ts - $state.0 > $max_len OR $row.ts - $state.1 > $timeout;
+ $new_state = AsTuple(IF($is_end_session, $row.ts, $state.0), $row.ts);
+ return AsTuple($is_end_session, $new_state);
+};
+$calculate = ($row, $state) -> ($row.ts);
+SELECT
+ user,
+ session_start,
+ SessionStart() AS same_session_start, -- It's same as session_start
+ COUNT(*) AS session_size,
+ SUM(value) AS sum_over_session,
+FROM my_table
+GROUP BY user, SessionWindow(ts, $init, $update, $calculate) AS session_start
+```
+
+You can use SessionWindow in GROUP BY only once.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/insert_into.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/insert_into.md
new file mode 100644
index 00000000000..77e20b4789e
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/insert_into.md
@@ -0,0 +1,62 @@
+# INSERT INTO
+
+{% if select_command != "SELECT STREAM" %} Adds rows to the table. {% if feature_bulk_tables %} If the target table already exists and is not sorted, the operation `INSERT INTO` adds rows at the end of the table. In the case of a sorted table, YQL tries to preserve sorting by running a sorted merge. {% endif %}{% if feature_map_tables %} If you try to insert a row into a table with an existing primary key value, the operation fails with the `PRECONDITION_FAILED` error code and the `Operation aborted due to constraint violation: insert_pk` message returned.{% endif %}
+
+{% if feature_mapreduce %}The table is searched by name in the database specified by the [USE](../use.md) operator.{% endif %}
+
+`INSERT INTO` lets you perform the following operations:
+
+* Adding constant values using [`VALUES`](../values.md).
+
+ ```sql
+ INSERT INTO my_table (Key1, Key2, Value1, Value2)
+ VALUES (345987,'ydb', 'Pied piper', 1414);
+ COMMIT;
+ ```
+
+ ```sql
+ INSERT INTO my_table (key, value)
+ VALUES ("foo", 1), ("bar", 2);
+ ```
+
+* Saving the `SELECT` result.
+
+ ```sql
+ INSERT INTO my_table
+ SELECT Key AS Key1, "Empty" AS Key2, Value AS Value1
+ FROM my_table1;
+ ```
+
+{% if feature_insert_with_truncate %} To clear the table of the prior data before writing to it, add the modifier: `INSERT INTO ... WITH TRUNCATE`.
+
+**Examples:**
+
+```yql
+INSERT INTO my_table WITH TRUNCATE
+SELECT key FROM my_table_source;
+```
+
+{% endif %}
+
+{% else %}
+
+Send the result of the [SELECT STREAM](../select_stream.md) calculation to the specified stream on the cluster specified by the [USE](../use.md) operator. The stream must exist and have a scheme matching the query result.
+
+**Examples:**
+
+```yql
+INSERT INTO my_stream_dst
+SELECT STREAM key FROM my_stream_src;
+```
+
+You can specify a table on the ydb cluster as the target. The table must exist at the time you create the operation. The table schema must be compatible with the type of query result.
+
+**Examples:**
+
+```yql
+INSERT INTO ydb_cluster.`my_table_dst`
+SELECT STREAM * FROM rtmr_cluster.`my_stream_source`;
+```
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/into_result.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/into_result.md
new file mode 100644
index 00000000000..5386bbb7bda
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/into_result.md
@@ -0,0 +1,17 @@
+# INTO RESULT
+
+Lets you set a custom label for [SELECT](../select.md){% if feature_mapreduce and process_command == "PROCESS" %}, [PROCESS](../process.md), or [REDUCE](../reduce.md){% endif %}. It can't be used along with [DISCARD](../discard.md).
+
+**Examples:**
+
+```yql
+SELECT 1 INTO RESULT foo;
+```
+
+```yql
+SELECT * FROM
+my_table
+WHERE value % 2 == 0
+INTO RESULT `Result name`;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/join.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/join.md
new file mode 100644
index 00000000000..0a103d5726d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/join.md
@@ -0,0 +1,130 @@
+# JOIN
+
+It lets you combine multiple data sources (subqueries or tables) by equality of values in the specified columns or expressions (the `JOIN` keys).
+
+**Syntax**
+
+```sql
+SELECT ... FROM table_1
+-- The first JOIN step:
+ <Join_Type> JOIN table_2 <Join_Condition>
+ -- The left-hand selection -- entries in table_1
+ -- The right-hand selection -- entries in table_2
+-- The next JOIN step:
+ <Join_Type> JOIN table_n <Join_Condition>
+ -- The left-hand selection is the JOIN result in the previous step
+ -- The right-hand selection are entries in table_n
+-- JOIN can include the following steps
+...
+WHERE ...
+```
+
+At each JOIN step, rules are used to establish correspondences between rows in the left-hand and right-hand data selections, creating a new selection that includes every combination of rows that meet the JOIN conditions.
+
+{% note warning %}
+
+Since columns in YQL are identified by their names, and you can't have two columns with the same name in the selection, `SELECT * FROM ... JOIN ...` can't be executed if there are columns with identical names in the joined tables.
+
+{% endnote %}
+
+## Types of join (Join_Type)
+
+* `INNER` <span style="color: gray;">(default)</span>: Rows from the joined selections that match no row on the other side won't be included in the result.
+* `LEFT`: If there's no value in the right-hand selection, it adds a row to the result with column values from the left-hand selection, using `NULL` in columns from the right-hand selection
+* `RIGHT`: If there's no value in the left-hand selection, it adds the row to the result, including column values from the right-hand selection, but using `NULL` in columns from the left-hand selection
+* `FULL` = `LEFT` + `RIGHT`
+* `LEFT/RIGHT SEMI`: One side of the query is a whitelist of keys, its values are not available. The result includes columns from one table only, no cartesian product is created.
+* `LEFT/RIGHT ONLY`: Subtracting the sets by keys (blacklist). It's almost equivalent to adding `IS NULL` to the key on the opposite side in the regular `LEFT/RIGHT JOIN`, but with no access to values, same as in `SEMI` JOIN.
+* `CROSS`: A full cartesian product of two tables without specifying key columns and no explicit `ON/USING`.
+* `EXCLUSION`: Both sides minus the intersection.
+
+![](../_assets/join-YQL-06.png)
+
+{% note info %}
+
+`NULL` is a special value to denote nothing. Hence, `NULL` values on both sides are **NOT** treated as equal to each other. This eliminates ambiguity in some types of `JOIN` and avoids a giant Cartesian product otherwise created.
+
+{% endnote %}
+
+## Conditions for joining (Join_Condition)
+
+For `CROSS JOIN`, no join condition is specified. The result includes the Cartesian product of the left-hand and right-hand selection, that is, combines everything with everything. The number of rows in the result selection is the product of the number of rows in the left-hand and right-hand selections.
+
+For any other JOIN types, specify the condition using one of the two methods:
+
+1. `USING (column_name)`. Used if both the left-hand and right-hand selections share a column whose equality of values is a join condition.
+2. `ON (equality_conditions)`. Lets you set a condition of equality for column values or expressions over columns in the left-hand and right-hand selections or use several such conditions combined by `and`.
+
+**Examples:**
+
+```sql
+SELECT a.value as a_value, b.value as b_value
+FROM a_table AS a
+FULL JOIN b_table AS b USING (key);
+```
+
+```sql
+SELECT a.value as a_value, b.value as b_value
+FROM a_table AS a
+FULL JOIN b_table AS b ON a.key = b.key;
+```
+
+```sql
+SELECT a.value as a_value, b.value as b_value, c.column2
+FROM a_table AS a
+CROSS JOIN b_table AS b
+LEFT JOIN c_table AS c ON c.ref = a.key and c.column1 = b.value;
+```
+
+{% if feature_mapreduce %}
+If the statement filters data in addition to `JOIN`, we recommend that you wrap the criteria that would return `true` for most of the rows in the `LIKELY(...)` function call. If your assumption that positive values prevail for the criteria is correct, such a hint might speed up your query. `LIKELY` can be useful when the predicate calculation is a resource-intensive operation and JOIN significantly reduces the number of rows.
+
+In front of any data source for `JOIN`, you can add the `ANY` keyword to suppress duplicate `JOIN` keys on the given side. In this case, only one row is left from the set of rows with the same `JOIN` key value (no matter which one, that's why the keyword is called `ANY`).
+This syntax differs from the one used in [ClickHouse]{% if lang == "en" %}(https://clickhouse.com/docs/en/sql-reference/statements/select/join/){% endif %}{% if lang == "ru" %}(https://clickhouse.tech/docs/ru/sql-reference/statements/select/join/){% endif %}where `ANY` is placed before the `JOIN` type and applies to the right side only.
+
+Request
+
+```yql
+$t1 = AsList(
+ AsStruct("1" AS key, "v111" AS value),
+ AsStruct("2" AS key, "v121" AS value),
+ AsStruct("2" AS key, "v122" AS value),
+ AsStruct("3" AS key, "v131" AS value),
+ AsStruct("3" AS key, "v132" AS value));
+
+$t2 = AsList(
+ AsStruct("2" AS key, "v221" AS value),
+ AsStruct("2" AS key, "v222" AS value),
+ AsStruct("3" AS key, "v231" AS value),
+ AsStruct("3" AS key, "v232" AS value),
+ AsStruct("4" AS key, "v241" AS value));
+
+SELECT
+ a.key, a.value, b.value
+FROM ANY AS_TABLE($t1) AS a
+JOIN ANY AS_TABLE($t2) AS b
+ON a.key == b.key;
+```
+
+results in:
+
+| a.key | a.value | b.value |
+| --- | --- | --- |
+| "3" | "v131" | "v231" |
+| "2" | "v121" | "v221" |
+
+and without `ANY` it would result in:
+
+| a.key | a.value | b.value |
+| --- | --- | --- |
+| "3" | "v131" | "v231" |
+| "3" | "v131" | "v232" |
+| "3" | "v132" | "v231" |
+| "3" | "v132" | "v232" |
+| "2" | "v121" | "v221" |
+| "2" | "v121" | "v222" |
+| "2" | "v122" | "v221" |
+| "2" | "v122" | "v222" |
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/lexer.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/lexer.md
new file mode 100644
index 00000000000..b9a1725bcb2
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/lexer.md
@@ -0,0 +1,163 @@
+# Lexical structure
+
+The {% if feature_mapreduce %}program {% else %}query {% endif %} in the YQL language is a valid UTF-8 text consisting of _commands_ (statements) separated by semicolons (`;`).
+The last semicolon can be omitted.
+Each command is a sequence of _tokens_ that are valid for this command.
+Tokens can be _keywords_, _IDs_, _literals_, and so on.
+Tokens are separated by whitespace characters (space, tab, line feed) or _comments_. The comment is not a part of the command and is syntactically equivalent to a space character.
+
+## Syntax compatibility modes {#lexer-modes}
+
+Two syntax compatibility modes are supported:
+
+* Advanced C++ (default)
+* ANSI SQL
+
+ANSI SQL mode is enabled with a special comment `--!ansi-lexer` that must be in the beginning of the {% if feature_mapreduce %}program{% else %}query{% endif %}.
+
+Specifics of interpretation of lexical elements in different compatibility modes are described below.
+
+## Comments {#comments}
+
+The following types of comments are supported:
+
+* Single-line comment: starts with `--` (two minus characters _following one another_) and continues to the end of the line
+* Multiline comment: starts with `/*` and ends with `*/`
+
+```sql
+SELECT 1; -- A single-line comment
+/*
+ Some multi-line comment
+*/
+```
+
+In C++ syntax compatibility mode (default), a multiline comment ends with the _nearest_ `*/`.
+The ANSI SQL syntax compatibility mode accounts for nesting of multiline comments:
+
+```sql
+--!ansi_lexer
+SELECT * FROM T; /* this is a comment /* this is a nested comment, without ansi_lexer it raises an error */ */
+```
+
+## Keywords and identifiers {#keywords-and-ids}
+
+**Keywords** are tokens that have a fixed value in the YQL language. Examples of keywords: `SELECT`, `INSERT`, `FROM`, `ACTION`, and so on. Keywords are case-insensitive, that is, `SELECT` and `SeLEcT` are equivalent to each other.
+The list of keywords is not fixed and is going to expand as the language develops. A keyword can't contain numbers and begin or end with an underscore.
+
+**Identifiers** are tokens that identify the names of tables, columns, and other objects in YQL. Identifiers in YQL are always case-sensitive.
+An identifier can be written in the body of the program without any special formatting, if the identifier:
+
+* Is not a keyword
+* Begins with a Latin letter or underscore
+* Is followed by a Latin letter, an underscore, or a number
+
+```sql
+SELECT my_column FROM my_table; -- my_column and my_table are identifiers
+```
+
+To include an arbitrary ID in the body of a {% if feature_mapreduce %}program{% else %}query{% endif %}, the ID is enclosed in backticks:
+
+```sql
+SELECT `column with space` from T;
+SELECT * FROM `my_dir/my_table`
+```
+
+IDs in backticks are never interpreted as keywords:
+
+```sql
+SELECT `select` FROM T; -- select - Column name in the T table
+```
+
+When using backticks, you can use the standard C escaping:
+
+```sql
+SELECT 1 as `column with\n newline, \x0a newline and \` backtick `;
+```
+
+In ANSI SQL syntax compatibility mode, arbitrary IDs can also be enclosed in double quotes. To include a double quote in a quoted ID, use two double quotes:
+
+```sql
+--!ansi_lexer
+SELECT 1 as "column with "" double quote"; -- column name will be: column with " double quote
+```
+
+## String literals {#string-literals}
+
+A string literal (constant) is expressed as a sequence of characters enclosed in single quotes. Inside a string literal, you can use the C-style escaping rules:
+
+```yql
+SELECT 'string with\n newline, \x0a newline and \' backtick ';
+```
+
+In the C++ syntax compatibility mode (default), you can use double quotes instead of single quotes:
+
+```yql
+SELECT "string with\n newline, \x0a newline and \" backtick ";
+```
+
+In ASNI SQL compatibility mode, double quotes are used for IDs, and the only escaping that can be used for string literals is a pair of single quotes:
+
+```sql
+--!ansi_lexer
+SELECT 'string with '' quote'; -- result: a string with a ' quote
+```
+
+### Multi-line string literals {#multiline-string-literals}
+
+A multiline string literal is expressed as an arbitrary set of characters enclosed in double at signs `@@`:
+
+```yql
+$text = @@some
+multiline
+text@@;
+SELECT LENGTH($text);
+```
+
+If you need to use double at signs in your text, duplicate them:
+
+```yql
+$text = @@some
+multiline with double at: @@@@
+text@@;
+SELECT $text;
+```
+
+### Typed string literals {#typed-string-literals}
+
+* For string literals, for example, [multiline](#multiline-string-literals) literals, the `String` type is used by default.
+* You can use the following suffixes to explicitly control the literal type:
+ * `u`: `Utf8`.
+ * `y`: `Yson`.
+ * `j`: `Json`.
+
+**Example:**
+
+```yql
+SELECT "foo"u, '[1;2]'y, @@{"a":null}@@j;
+```
+
+## Numeric literals {#literal-numbers}
+
+* Integer literals have the default type `Int32`, if they fit within the Int32 range. Otherwise, they automatically expand to `Int64`.
+* You can use the following suffixes to explicitly control the literal type:
+ * `l`: `Int64`.
+ * `s`: `Int16`.
+ * `t`: `Int8`.
+* Add the suffix `u` to convert a type to its corresponding unsigned type:
+ * `ul`: `Uint64`.
+ * `u`: `Uint32`.
+ * `us`: `Uint16`.
+ * `ut`: `Uint8`.
+* You can also use hexadecimal, octal, and binary format for integer literals using the prefixes `0x`, `0o` and `0b`, respectively. You can arbitrarily combine them with the above-mentioned suffixes.
+* Floating point literals have the `Double` type by default, but you can use the suffix `f` to narrow it down to `Float`.
+
+```sql
+SELECT
+ 123l AS `Int64`,
+ 0b01u AS `Uint32`,
+ 0xfful AS `Uint64`,
+ 0o7ut AS `Uint8`,
+ 456s AS `Int16`,
+ 1.2345f AS `Float`;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/not_yet_supported.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/not_yet_supported.md
new file mode 100644
index 00000000000..eb128a428d9
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/not_yet_supported.md
@@ -0,0 +1,18 @@
+# Classic SQL constructs not supported yet
+
+## \[NOT\] \[EXISTS|INTERSECT\|EXCEPT] {#not-exists}
+
+A syntactically available alternative is `EXISTS`, but it's not very useful as it doesn't support correlated subqueries. You can also rewrite it using `JOIN`.
+
+## UNION {#union}
+
+An available alternative is `SELECT DISTINCT` by explicitly listed columns + `UNION ALL` with subqueries (if needed).
+
+## NATURAL JOIN {#natural-join}
+
+An alternative is to explicitly list the matching columns on both sides.
+
+## NOW() / CURRENT_TIME() {#now}
+
+An alternative is to use the functions [CurrentUtcDate, CurrentUtcDatetime and CurrentUtcTimestamp](../../builtins/basic.md#current-utc).
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/debug.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/debug.md
new file mode 100644
index 00000000000..8b7cb79647b
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/debug.md
@@ -0,0 +1,41 @@
+{% if tech %}
+
+## Debugging and auxiliary settings {#debug}
+
+{% if feature_webui %}
+
+### `DirectRead`
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+An auxiliary setting for previewing tables in the [HTTP API](../../../interfaces/http.md) (both for the web interface and console client).
+{% endif %}
+
+### `config.flags("ValidateUdf", "Lazy")`
+
+| Value type | Default |
+| --- | --- |
+| String: None/Lazy/Greedy | None |
+
+Validating whether UDF results match the declared signature. The Greedy mode enforces materialization of lazy containers, although the Lazy mode doesn't.
+
+### `{{ backend_name_lower }}.DefaultCluster`
+
+| Value type | Default |
+| --- | --- |
+| A string with the cluster name | hahn |
+
+Selecting a cluster for calculations that don't access tables.
+
+### `config.flags("Diagnostics")`
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+Getting diagnostic information from YQL as an additional result of a query.
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/definition.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/definition.md
new file mode 100644
index 00000000000..dcc3cbe8888
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/definition.md
@@ -0,0 +1,39 @@
+## Definition
+
+Redefinition of settings.
+
+**Syntax**
+
+`PRAGMA x.y = "z";` or `PRAGMA x.y("z", "z2", "z3");`:
+
+* `x`: (optional) The category of the setting.
+* `y`: The name of the setting.
+* `z`: (optional for flags) The value of the setting. The following suffixes are acceptable:
+ * `Kb`, `Mb`, `Gb`: For the data amounts.
+ * `sec`, `min`, `h`, `d`: For the time values.
+
+**Examples**
+
+```yql
+PRAGMA AutoCommit;
+```
+
+```yql
+PRAGMA TablePathPrefix = "home/yql";
+```
+
+```yql
+PRAGMA Warning("disable", "1101");
+```
+
+With some exceptions, you can return the settings values to their default states using `PRAGMA my_pragma = default;`.
+
+For the full list of available settings, [see the table below](#pragmas).
+
+### Scope {#pragmascope}
+
+Unless otherwise specified, a pragma affects all the subsequent expressions up to the end of the module where it's used.
+If necessary and logically possible, you can change the value of this setting several times within a given query to make it different at different execution steps.
+There are also special scoped pragmas with the scope defined by the same rules as the scope of [named expressions](../../expressions.md#named-nodes).
+Unlike scoped pragmas, regular pragmas can only be used in the global scope (not inside lambda functions, ACTION{% if feature_subquery %}, SUBQUERY{% endif %}, etc.).
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/files.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/files.md
new file mode 100644
index 00000000000..835e96ce40f
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/files.md
@@ -0,0 +1,60 @@
+{% if feature_mapreduce %}
+
+## Working with files
+
+### File
+
+| Value type | Default | Static/<br/>dynamic |
+| --- | --- | --- |
+| Two string arguments: alias and URL | — | Static |
+
+Attach a file to the query by URL. For attaching files you can use the built-in functions [FilePath and FileContent](../../../builtins/basic.md#filecontent). This `PRAGMA` is a universal alternative to attaching files using built-in mechanisms from the [web](../../../interfaces/web.md#attach) or [console](../../../interfaces/cli.md#attach) clients.
+
+YQL reserves the right to cache files at the URL for an indefinite period, hence, if there is a significant change in the content behind it, we strongly recommended to modify the URL by adding/editing dummy parameters.
+
+### Folder
+
+| Value type | Default | Static/<br/>dynamic |
+| --- | --- | --- |
+| Two string arguments: prefix and URL | — | Static |
+
+Attach a set of files to the query by URL. Works similarly to adding multiple files via [`PRAGMA File`](#file) by direct links to files with aliases obtained by combining a prefix with a file name using `/`.
+
+### Library
+
+| Value type | Default | Static/<br/>dynamic |
+| --- | --- | --- |
+| One or two arguments: the file name and an optional URL | — | Static |
+
+Treat the specified attached file as a library from which you can do [IMPORT](../../export_import.md). The syntax type for the library is determined from the file extension:
+
+* `.sql`: For the YQL dialect of SQL <span style="color: green;">(recommended)</span>.
+* `.yql`: For [s-expressions](/docs/s_expressions).
+
+Example with a file attached to the query:
+
+```yql
+PRAGMA library("a.sql");
+IMPORT a SYMBOLS $x;
+SELECT $x;
+```
+
+If the URL is specified, the library is downloaded from the URL rather than from the pre-attached file as in the following example:
+
+```yql
+PRAGMA library("a.sql","https://paste.yandex-team.ru/5618566/text");
+IMPORT a SYMBOLS $x;
+SELECT $x;
+```
+
+In this case, you can use text parameter value substitution in the URL:
+
+```yql
+DECLARE $_ver AS STRING; -- "5618566"
+PRAGMA library("a.sql","https://paste.yandex-team.ru/{$_ver}/text");
+IMPORT a SYMBOLS $x;
+SELECT $x;
+```
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/global.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/global.md
new file mode 100644
index 00000000000..007c5d1336a
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/global.md
@@ -0,0 +1,204 @@
+## Global {#pragmas}
+
+### AutoCommit {#autocommit}
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+Automatically run [COMMIT](../../select.md#commit) after every statement.
+
+### TablePathPrefix {#table-path-prefix}
+
+| Value type | Default |
+| --- | --- |
+| String | — |
+
+Add the specified prefix to the cluster table paths. It uses standard file system path concatenation, supporting parent folder `..`referencing and requiring no trailing slash. For example,
+
+`PRAGMA TablePathPrefix = "home/yql";
+SELECT * FROM test;`
+
+The prefix is not added if the table name is an absolute path (starts with /).
+
+### Warning {#warning}
+
+| Value type | Default |
+| --- | --- |
+| 1. Action<br>2. Warning code or "*" | — |
+
+Action:
+
+* `disable`: Disable.
+* `error`: Treat as an error.
+* `default`: Revert to the default behavior.
+
+The warning code is returned with the text itself (it's displayed on the right side of the web interface).
+
+Example:
+`PRAGMA Warning("error", "*");`
+`PRAGMA Warning("disable", "1101");`
+`PRAGMA Warning("default", "4503");`
+
+In this case, all the warnings are treated as errors, except for the warning `1101` (that will be disabled) and `4503` (that will be processed by default, that is, remain a warning). Since warnings may be added in new YQL releases, use `PRAGMA Warning("error", "*");` with caution (at least cover such queries with autotests).
+
+{% include [issue_protos.md](issue_protos.md) %}
+
+{% if feature_mapreduce %}
+
+### DqEngine {#dqengine}
+
+| Value type | Default |
+| --- | --- |
+| disable/auto/force string | "auto" |
+
+When set to "auto", it enables a new compute engine. Computing is made, whenever possible, without creating map/reduce operations. When the value is "force", computing is made by the new engine unconditionally.
+{% endif %}
+
+{% if feature_join %}
+
+### SimpleColumns {#simplecolumns}
+
+`SimpleColumns` / `DisableSimpleColumns`
+
+| Value type | Default |
+| --- | --- |
+| Flag | true |
+
+When you use `SELECT foo.* FROM ... AS foo`, remove the `foo.` prefix from the names of the result columns.
+
+It can be also used with a [JOIN](../../join.md), but in this case it may fail in the case of a name conflict (that can be resolved by using [WITHOUT](../../select.md#without) and renaming columns). For JOIN in SimpleColumns mode, an implicit Coalesce is made for key columns: the query `SELECT * FROM T1 AS a JOIN T2 AS b USING(key)` in the SimpleColumns mode works same as `SELECT a.key ?? b.key AS key, ... FROM T1 AS a JOIN T2 AS b USING(key)`.
+
+### CoalesceJoinKeysOnQualifiedAll
+
+`CoalesceJoinKeysOnQualifiedAll` / `DisableCoalesceJoinKeysOnQualifiedAll`
+
+| Value type | Default |
+| --- | --- |
+| Flag | true |
+
+Controls implicit Coalesce for the key `JOIN` columns in the SimpleColumns mode. If the flag is set, the Coalesce is made for key columns if there is at least one expression in the format `foo.*` or `*` in SELECT: for example, `SELECT a.* FROM T1 AS a JOIN T2 AS b USING(key)`. If the flag is not set, then Coalesce for JOIN keys is made only if there is an asterisk '*' after `SELECT`
+
+### StrictJoinKeyTypes
+
+`StrictJoinKeyTypes` / `DisableStrictJoinKeyTypes`
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+If the flag is set, then [JOIN](../../join.md) will require strict matching of key types.
+By default, JOIN preconverts keys to a shared type, which might result in performance degradation.
+StrictJoinKeyTypes is a [scoped](#pragmascope) setting.
+
+{% endif %}
+
+### AnsiInForEmptyOrNullableItemsCollections
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+This pragma brings the behavior of the `IN` operator in accordance with the standard when there's `NULL` in the left or right side of `IN`. The behavior of `IN` when on the right side there is a Tuple with elements of different types also changed. Examples:
+
+`1 IN (2, 3, NULL) = NULL (was Just(False))`
+`NULL IN () = Just(False) (was NULL)`
+`(1, null) IN ((2, 2), (3, 3)) = Just(False) (was NULL)`
+`2147483648u IN (1, 2147483648u) = True (was False)`
+
+For more information about the `IN` behavior when operands include `NULL`s, see [here](../../expressions.md#in). You can explicitly select the old behavior by specifying the pragma `DisableAnsiInForEmptyOrNullableItemsCollections`. If no pragma is set, then a warning is issued and the old version works.
+
+### AnsiRankForNullableKeys
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+Aligns the RANK/DENSE_RANK behavior with the standard if there are optional types in the window sort keys or in the argument of such window functions. It means that:
+
+* The result type is always Uint64 rather than Uint64?.
+* NULLs in keys are treated as equal to each other (the current implementation returns NULL).
+You can explicitly select the old behavior by using the `DisableAnsiRankForNullableKeys` pragma. If no pragma is set, then a warning is issued and the old version works.
+
+### AnsiOrderByLimitInUnionAll
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+Aligns the UNION ALL behavior with the standard if there is `ORDER BY/LIMIT/DISCARD/INSERT INTO` in the combined subqueries. It means that:
+
+* `ORDER BY/LIMIT/INSERT INTO` are allowed only after the last subquery.
+* `DISCARD` is allowed only before the first subquery.
+* The specified operators apply to the `UNION ALL` result (unlike the current behavior when they apply only to the subquery).
+* To apply an operator to a subquery, enclose the subquery in parentheses.
+
+You can explicitly select the old behavior by using the `DisableAnsiOrderByLimitInUnionAll` pragma. If no pragma is set, then a warning is issued and the old version works.
+
+### OrderedColumns {#orderedcolumns}
+
+`OrderedColumns`/`DisableOrderedColumns`
+
+Output the [column order](../../select.md#orderedcolumns) in SELECT/JOIN/UNION ALL and preserve it when writing the results. The order of columns is undefined by default.
+
+### PositionalUnionAll {#positionalunionall}
+
+Enable the standard column-by-column execution for [UNION ALL](../../select.md#unionall). This automatically enables
+[ordered columns](#orderedcolumns).
+
+### RegexUseRe2
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+Use Re2 UDF instead of Pcre to execute SQL the `REGEX`,`MATCH`,`RLIKE` statements. Re2 UDF can properly handle Unicode characters, unlike the default Pcre UDF.
+
+### ClassicDivision
+
+| Value type | Default |
+| --- | --- |
+| Flag | true |
+
+In the classical version, the result of integer division remains integer (by default).
+If disabled, the result is always Double.
+ClassicDivision is a [scoped](#pragmascope) setting.
+
+### AllowDotInAlias
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+Enable dot in names of result columns. This behavior is disabled by default, since the further use of such columns in JOIN is not fully implemented.
+
+### WarnUnnamedColumns
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+Generate a warning if a column name was automatically generated for an unnamed expression in `SELECT` (in the format `column[0-9]+`).
+
+### GroupByLimit
+
+| Value type | Default |
+| --- | --- |
+| Positive number | 32 |
+
+Increasing the limit on the number of dimensions in [GROUP BY](../../group_by.md).
+
+{% if feature_group_by_rollup_cube %}
+
+### GroupByCubeLimit
+
+| Value type | Default |
+| --- | --- |
+| Positive number | 5 |
+
+Increasing the limit on the number of dimensions in [GROUP BY](../../group_by.md#rollup-cube-group-sets).
+
+Use this option with care, because the computational complexity of the query grows exponentially with the number of dimensions.
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/issue_protos.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/issue_protos.md
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/issue_protos.md
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/ydb.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/ydb.md
new file mode 100644
index 00000000000..1cca5678d8c
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/ydb.md
@@ -0,0 +1,14 @@
+{% if tech %}
+
+## YDB
+
+### `kikimr.IsolationLevel`
+
+| Value type | Default |
+| --- | --- |
+| Serializable, ReadCommitted, ReadUncommitted, or ReadStale. | Serializable |
+
+An experimental pragma that allows you to reduce the isolation level of the current YDB transaction.
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/yson.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/yson.md
new file mode 100644
index 00000000000..50058c132f1
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/pragma/yson.md
@@ -0,0 +1,28 @@
+## Yson
+
+Managing the default behavior of Yson UDF, for more information, see the [documentation](../../../udf/list/yson.md) and, in particular, [Yson::Options](../../../udf/list/yson.md#ysonoptions).
+
+### `yson.AutoConvert`
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+Automatic conversion of values to the required data type in all Yson UDF calls, including implicit calls.
+
+### `yson.Strict`
+
+| Value type | Default |
+| --- | --- |
+| Flag | true |
+
+Strict mode control in all Yson UDF calls, including implicit calls. If the value is omitted or is `"true"`, it enables the strict mode. If the value is `"false"`, it disables the strict mode.
+
+### `yson.DisableStrict`
+
+| Value type | Default |
+| --- | --- |
+| Flag | false |
+
+An inverted version of `yson.Strict`. If the value is omitted or is `"true"`, it disables the strict mode. If the value is `"false"`, it enables the strict mode.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/process.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/process.md
new file mode 100644
index 00000000000..ca562566fea
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/process.md
@@ -0,0 +1,127 @@
+# {{ process_command }}
+
+Convert the input table using a UDF in [C++](../../udf/cpp.md){% if yt %}, [Python](../../udf/python.md) or [JavaScript](../../udf/javascript.md){% endif %} or a [lambda function](../../syntax/expressions.md#lambda) that is applied sequentially to each input row and can create zero to create one or more result row for each input row (similarly to Map in MapReduce terms).
+
+{% if feature_mapreduce %}The table is searched by name in the database specified by the [USE](../use.md) operator.{% endif %}
+
+The parameters of the function call after the `USING` keyword explicitly specify the values of columns from which to pass values for each input row and in which order.
+
+You can use functions that return the result of one of three composite types derived from `OutputType` (supported `OutputType` options are described below):
+
+* `OutputType`: Each input row must always have an output row with the schema determined by the structure type.
+* `OutputType?`: The function may skip rows, returning empty values (`TUnboxedValue()` in C++, `None` in Python, or `null` in JavaScript).
+* `Stream<OutputType>` or `List<OutputType>`: An option to return multiple rows.
+
+Regardless of the option selected above, the result is converted to a flat table with columns defined by the `OutputType` type.
+
+As `OutputType`, you can use one of the types:
+
+* `Struct<...>`: `{{ process_command }}` has exactly one output with entries of a given structure that is a flat table with columns corresponding to the fields `Struct<...>`
+* `Variant<Struct...>,...>`: `{{ process_command }}` will have the number of outputs equal to the number of variants in `Variant`. The entries of each output are represented by a flat table with columns based on fields from the relevant variant. In this case, you can access the set of `{{ process_command }}` outputs as a `Tuple` of lists that can be unpacked into separate [named expressions](../expressions.md#named-nodes) and used independently.
+
+In the list of function arguments after the `USING` keyword, you can pass one of the two special named expressions:
+
+* `TableRow()`: The entire current row in the form of a structure.
+* `TableRows()`: A lazy iterator by strings, in terms of the types `Stream<Struct...>>`. In this case, the output type of the function can only be `Stream<OutputType>` or `List<OutputType>`.
+
+{% note info %}
+
+After executing `{{ process_command }}`, within the same query, on the resulting table (or tables), you can perform {% if select_command != "SELECT STREAM" %}[SELECT](../select.md), [REDUCE](../reduce.md){% else %}[SELECT STREAM](../select_stream.md){% endif %}, [INSERT INTO](../insert_into.md), other `{{ process_command }}` and so on, depending on the intended result.
+
+{% endnote %}
+
+The `USING` keyword and the function are optional: if you omit them, the source table is returned. {% if feature_subquery %}This can be convenient for using a [subquery template](subquery.md).{% endif %}
+
+In `{{ process_command }}` you can pass multiple inputs (the input here means a table,{% if select_command != "PROCESS STREAM" %} a [range of tables](../select.md#range){% endif %}, a subquery, a [named expression](../expressions.md#named-nodes)), separated by commas. To the function from `USING`, you can only pass in this case special named expressions `TableRow()` or `TableRows()` that will have the following type:
+
+* `TableRow()`: A `Variant` where each element has an entry structure type from the relevant input. For each input row in the Variant, the element corresponding to the occurrence ID for this row is non-empty
+* `TableRows()`: A lazy iterator by Variants, in terms of the types `Stream<Variant...>>`. The alternative has the same semantics as for `TableRow()`
+
+After `USING` in `{{ process_command }}` you can optionally specify `ASSUME ORDER BY` with a list of columns. The result of such a `{{ process_command }}` statement is treated as sorted, but without actually running a sort. Sort check is performed at the query execution stage. It supports setting the sort order using the keywords `ASC` (ascending order) and `DESC` (descending order). Expressions are not supported in `ASSUME ORDER BY`.
+
+**Examples:**
+
+{% if process_command != "PROCESS STREAM" %}
+
+```yql
+PROCESS my_table
+USING MyUdf::MyProcessor(value)
+```
+
+```yql
+$udfScript = @@
+def MyFunc(my_list):
+ return [(int(x.key) % 2, x) for x in my_list]
+@@;
+
+-- The function returns an iterator of Variants
+$udf = Python3::MyFunc(Callable<(Stream<Struct<...>>) -> Stream<Variant<Struct<...>, Struct<...>>>>,
+ $udfScript
+);
+
+-- The output of the PROCESS produces a tuple of lists
+$i, $j = (PROCESS my_table USING $udf(TableRows()));
+
+SELECT * FROM $i;
+SELECT * FROM $j;
+```
+
+```yql
+$udfScript = @@
+def MyFunc(stream):
+ for r in stream:
+ yield {"alt": r[0], "key": r[1].key}
+@@;
+
+-- The function accepts an iterator of Variants as input
+$udf = Python::MyFunc(Callable<(Stream<Variant<Struct<...>, Struct<...>>>) -> Stream<Struct<...>>>,
+ $udfScript
+);
+
+PROCESS my_table1, my_table2 USING $udf(TableRows());
+```
+
+{% else %}
+
+```yql
+
+-- The lambda function accepts a primitive type and returns a structure with three identical fields
+$f = ($r) -> {
+ return AsStruct($r as key, $r as subkey, $r as value);
+};
+
+-- Filtering the input stream by the WHERE clause
+PROCESS STREAM Input USING $f(value) WHERE cast(subkey as int) > 3;
+```
+
+```yql
+-- The lambda function accepts the type `Struct<key:String, subkey:String, value:String>`
+-- and returns a similar structure by adding a suffix to each field
+
+$f = ($r) -> {
+ return AsStruct($r.key || "_1" as key, $r.subkey || "_2" as subkey, $r.value || "_3" as value);
+};
+
+PROCESS STREAM Input USING $f(TableRow());
+```
+
+```yql
+-- The lambda function accepts an entry in the format `Struct<...>`
+-- and returns a list of two identical items
+$f1 = ($x) -> {
+ return AsList($x, $x);
+};
+
+-- The lambda function accepts and returns the type `Stream<Struct...>>`
+-- It applies the $f1 function to each element and returns duplicate rows
+$f2 = ($x) -> {
+ return ListFlatMap($x, $f1);
+};
+
+$p = (PROCESS STREAM Input USING $f2(TableRows()));
+
+SELECT STREAM * FROM $p;
+```
+
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/reduce.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/reduce.md
new file mode 100644
index 00000000000..ca0bf7fb5f0
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/reduce.md
@@ -0,0 +1,104 @@
+# REDUCE
+
+Groups the input by the specified key columns, then passes the current keys and a lazy iterator over their corresponding values from the remaining columns to the specified UDF for processing. Similarly to `PROCESS`, the UDF can return an arbitrary number of result rows per call and also return `Variants` to create multiple outputs. In terms of MapReduce, it's very similar to Reduce.
+
+Keywords that can follow:
+
+* `PRESORT` <span style="color: gray;">(optional)</span>: Specifying the order within each group, the syntax is similar to [ORDER BY](../select.md#orderby);
+* `ON` <span style="color: gray;">(required)</span>: Specifying key columns.
+* `USING` or `USING ALL` <span style="color: gray;">(required)</span>: A UDF call, see more about the rules below.
+
+Rules for passing UDF arguments:
+
+* If `TableRows()` is specified as a UDF argument, then the UDF must accept one argument: a lazy iterator over strings, with the type `Stream<Struct...>>`. In this case, the output type of the function can only be `Stream<OutputType>` or `List<OutputType>`. It's guaranteed that the data in the input iterator is grouped by the key and, if necessary, sorted according to the `PRESORT` section. With `TableRows()`, you can only use `USING ALL`.
+* With `USING`:
+ * The UDF must accept two arguments: the current key is passed to the first argument, and a lazy iterator with values corresponding to this key is passed to the second argument.
+* With `USING ALL`:
+ * The UDF must accept one argument: a lazy iterator over `Tuples`, where the first item in the tuple is a key, and the second item is a lazy iterator with values corresponding to this key.
+* The key to be passed to the UDF follows the rule below. If there is only one key column, then only its value is used in the key. If there are multiple columns (columns are listed similarly to `GROUP BY` separated by commas), then the key is a `Tuple` with values from the listed columns in the specified order.
+* When you call `REDUCE` from a query, only the expression whose values will be passed as iterator items follows the UDF name in parentheses (the second UDF argument for `USING` or the second item of the tuple for `USING ALL`).
+
+The result is built in the same way as for [PROCESS](../process.md). You can also use the `TableRow()` keyword to get the whole string as a structure.
+
+In `REDUCE`, you can pass multiple inputs (the input here means a table, a [range of tables](../select.md#range), a subquery, a [named expression](../expressions.md#named-nodes)), separated by commas. All inputs must have the key columns of the matching type specified in `ON`. To the function from `USING` in this case, you can only pass a special named expression `TableRow()`. The second argument (or the second element of the tuple for `USING ALL`) will include a lazy iterator over variants with a populated element that corresponds to the occurrence ID for the current entry.
+
+After `USING`, in `REDUCE` you can optionally specify `ASSUME ORDER BY` with a list of columns. The result of such a `REDUCE` statement is treated as sorted, but without actually running a sort. Sort check is performed at the query execution stage. It supports setting the sort order using the keywords `ASC` (ascending order) and `DESC` (descending order). Expressions are not supported in `ASSUME ORDER BY`.
+
+**Examples:**
+
+```yql
+REDUCE my_table
+ON key, subkey
+USING MyUdf::MyReducer(TableRow());
+```
+
+```yql
+REDUCE my_table
+ON key, subkey
+USING ALL MyUDF::MyStreamReducer(TableRow()); -- MyUDF::MyStreamReducer accepts a lazy list of tuples (key, list of entries for the key) as its input
+```
+
+```yql
+REDUCE my_table
+PRESORT LENGTH(subkey) DESC
+ON key
+USING MyUdf::MyReducer(
+ AsTuple(subkey, value)
+);
+```
+
+```yql
+REDUCE my_table
+ON key
+USING ALL MyUDF::MyFlatStreamReducer(TableRows()); -- MyUDF::MyFlatStreamReducer accepts a single lazy list of entries as its input
+```
+
+```yql
+-- The function returns Variants
+$udf = Python::MyReducer(Callable<(String, Stream<Struct<...>>) -> Variant<Struct<...>, Struct<...>>>,
+ $udfScript
+);
+
+-- The output of REDUCE produces a tuple of lists
+$i, $j = (REDUCE my_table ON key USING $udf(TableRow()));
+
+SELECT * FROM $i;
+SELECT * FROM $j;
+```
+
+```yql
+$script = @@
+def MyReducer(key, values):
+ state = None, 0
+ for name, last_visit_time in values:
+ if state[1] < last_visit_time:
+ state = name, last_visit_time
+ return {
+ 'region':key,
+ 'last_visitor':state[0],
+ }
+@@;
+
+$udf = Python::MyReducer(Callable<(
+ Int64?,
+ Stream<Tuple<String?, Uint64?>>
+) -> Struct<
+ region:Int64?,
+ last_visitor:String?
+>>,
+ $script
+);
+
+REDUCE hahn.`home/yql/tutorial/users`
+ON region USING $udf((name, last_visit_time));
+```
+
+```yql
+-- The function accepts a key and iterator of Variants as input
+$udf = Python::MyReducer(Callable<(String, Stream<Variant<Struct<...>,Struct<...>>>) -> Struct<...>>,
+ $udfScript
+);
+
+REDUCE my_table1, my_table2 ON key USING $udf(TableRow());
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/replace_into.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/replace_into.md
new file mode 100644
index 00000000000..08891bdce5d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/replace_into.md
@@ -0,0 +1,32 @@
+# REPLACE INTO
+
+Saves data to a table, overwriting the rows based on the primary key.{% if feature_mapreduce %} The table is searched by name in the database specified by the [USE](../use.md) operator.{% endif %} If the given primary key is missing, a new row is added to the table. If the given `PRIMARY_KEY` exists, the row is overwritten. The values of columns not involved in the operation are replaced by their default values.
+
+{% note info %}
+
+Unlike [`INSERT INTO`](../insert_into.md) and [`UPDATE`](../update.md), the queries [`UPSERT INTO`](../upsert_into.md) and `REPLACE INTO` don't need to pre-fetch the data, hence they run faster.
+
+{% endnote %}
+
+* Setting values for `REPLACE INTO` using `VALUES`.
+
+ **Example**
+
+ ```sql
+ REPLACE INTO my_table (Key1, Key2, Value2) VALUES
+ (1u, "One", 101),
+ (2u, "Two", 102);
+ COMMIT;
+ ```
+
+* Fetching values for `REPLACE INTO` using a `SELECT`.
+
+ **Example**
+
+ ```sql
+ REPLACE INTO my_table
+ SELECT Key AS Key1, "Empty" AS Key2, Value AS Value1
+ FROM my_table1;
+ COMMIT;
+ ```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/assume_order_by.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/assume_order_by.md
new file mode 100644
index 00000000000..4a4cf404983
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/assume_order_by.md
@@ -0,0 +1,14 @@
+## ASSUME ORDER BY
+
+Checking that the `SELECT` result is sorted by the value in the specified column or multiple columns. The result of such a `SELECT` statement is treated as sorted, but without actually running a sort. Sort check is performed at the query execution stage.
+
+As in case of `ORDER BY`, it supports setting the sort order using the keywords `ASC` (ascending order) and `DESC` (descending order). Expressions are not supported in `ASSUME ORDER BY`.
+
+**Examples:**
+
+```yql
+SELECT key || "suffix" as key, -CAST(subkey as Int32) as subkey
+FROM my_table
+ASSUME ORDER BY key, subkey DESC;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/calc.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/calc.md
new file mode 100644
index 00000000000..09bc26c7f5b
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/calc.md
@@ -0,0 +1,16 @@
+## SELECT
+
+Returns the result of evaluating the expressions specified after `SELECT`.
+
+It can be used in combination with other operations to obtain other effect.
+
+**Examples:**
+
+```yql
+SELECT "Hello, world!";
+```
+
+```yql
+SELECT 2 + 2;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/column_order.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/column_order.md
new file mode 100644
index 00000000000..35d73225406
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/column_order.md
@@ -0,0 +1,25 @@
+## Column order in YQL {#orderedcolumns}
+
+The standard SQL is sensitive to the order of columns in projections (that is, in `SELECT`). While the order of columns must be preserved in the query results or when writing data to a new table, some SQL constructs use this order.
+This applies, for example, to [UNION ALL](#unionall) and positional [ORDER BY](#orderby) (ORDER BY ordinal).
+
+The column order is ignored in YQL by default:
+
+* The order of columns in the output tables and query results is undefined
+* The data scheme of the `UNION ALL` result is output by column names rather than positions
+
+If you enable `PRAGMA OrderedColumns;`, the order of columns is preserved in the query results and is derived from the order of columns in the input tables using the following rules:
+
+* `SELECT`: an explicit column enumeration dictates the result order.
+* `SELECT` with an asterisk (`SELECT * FROM ...`) inherits the order from its input.
+{% if feature_join %}* The order of columns after [JOIN](../../join.md): First output the left-hand columns, then the right-hand ones. If the column order in any of the sides in the `JOIN` output is undefined, the column order in the result is also undefined.{% endif %}
+* The order in `UNION ALL` depends on the [UNION ALL](#unionall) execution mode.
+* The column order for [AS_TABLE](#as_table) is undefined.
+
+{% note warning %}
+
+In the YT table schema, key columns always precede non-key columns. The order of key columns is determined by the order of the composite key.
+When `PRAGMA OrderedColumns;` is enabled, non-key columns preserve their output order.
+
+{% endnote %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/commit.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/commit.md
new file mode 100644
index 00000000000..0f42606613d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/commit.md
@@ -0,0 +1,17 @@
+## COMMIT {#commit}
+
+By default, the entire YQL query is executed within a single transaction, and independent parts inside it are executed in parallel, if possible.
+Using the `COMMIT;` keyword you can add a barrier to the execution process to delay execution of expressions that follow until all the preceding expressions have completed.
+
+To commit in the same way automatically after each expression in the query, you can use `PRAGMA autocommit;`.
+
+**Examples:**
+
+```yql
+INSERT INTO result1 SELECT * FROM my_table;
+INSERT INTO result2 SELECT * FROM my_table;
+COMMIT;
+-- result2 will already include the SELECT contents from the second line:
+INSERT INTO result3 SELECT * FROM result2;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/distinct.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/distinct.md
new file mode 100644
index 00000000000..4c1a31cc9b3
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/distinct.md
@@ -0,0 +1,19 @@
+## DISTINCT {#distinct}
+
+Selecting unique rows.
+
+{% note info %}
+
+Applying `DISTINCT` to calculated values is not currently implemented. For this purpose, use a subquery or the clause [`GROUP BY ... AS ...`](../../group_by.md).
+
+{% endnote %}
+
+**Example**
+
+```yql
+SELECT DISTINCT value -- only unique values from the table
+FROM my_table;
+```
+
+The `DISTINCT` keyword can also be used to apply [aggregate functions](../../../builtins/aggregation.md) only to distinct values. For more information, see the documentation for [GROUP BY](../../group_by.md).
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/execution.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/execution.md
new file mode 100644
index 00000000000..73256e8b7a9
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/execution.md
@@ -0,0 +1,20 @@
+## SELECT execution procedure {#selectexec}
+
+The `SELECT` query result is calculated as follows:
+
+* Determine the set of input tables by evaluating the [FROM](#from) clauses.
+* Apply [SAMPLE](#sample)/[TABLESAMPLE](#sample) to input tables.
+* Execute [FLATTEN COLUMNS](../../flatten.md#flatten-columns) or [FLATTEN BY](../../flatten.md); aliases set in `FLATTEN BY` become visible after this point.
+{% if feature_join %}* Execute every [JOIN](../../join.md).{% endif %}
+* Add to (or replace in) the data the columns listed in [GROUP BY ... AS ...](../../group_by.md).
+* Execute [WHERE](#where) &mdash; Discard all the data mismatching the predicate.
+* Execute [GROUP BY](../../group_by.md), evaluate aggregate functions.
+* Apply the filter [HAVING](../../group_by.md#having).
+{% if feature_window_functions %} * Evaluate [window functions](../../window.md);{% endif %}
+* Evaluate expressions in `SELECT`.
+* Assign names set by aliases to expressions in `SELECT`.
+* Apply top-level [DISTINCT](#distinct) to the resulting columns.
+* Execute similarly every subquery inside [UNION ALL](#unionall), combine them (see [PRAGMA AnsiOrderByLimitInUnionAll](../../pragma.md#pragmas)).
+* Perform sorting with [ORDER BY](#order-by).
+* Apply [OFFSET and LIMIT](#limit-offset) to the result.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/folder.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/folder.md
new file mode 100644
index 00000000000..c1d275027ff
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/folder.md
@@ -0,0 +1,44 @@
+## Listing the contents of a directory in a cluster {#folder}
+
+It's expressed as the `FOLDER` function in [FROM](#from).
+
+Arguments:
+
+1. The path to the directory.
+2. An optional string with a list of meta attributes separated by a semicolon.
+
+The result is a table with three fixed columns:
+
+1. **Path** (`String`): The full name of the table.
+2. **Type** (`String`): The node type (table, map_node, file, document, and others).
+3. **Attributes** (`Yson`) is a Yson dictionary with meta attributes ordered in the second argument.
+
+Recommendations for use:
+
+* To get only a list of tables, make sure to add `...WHERE Type == "table"`. Then, by optionally adding more conditions, you can use the aggregate function [AGGREGATE_LIST](../../../builtins/aggregation.md#aggregate-list) from the Path column to get only a list of paths and pass them to [EACH](#each).
+* Since the Path column is output in the same format as the result of the function [TablePath()](../../../builtins/basic.md#tablepath), then they can be used to JOIN table attributes to its rows.
+* We recommend that you work with the Attributes column using [Yson UDF](../../../udf/list/yson.md).
+
+{% note warning %}
+
+Use FOLDER with attributes containing large values with caution (`schema` could be one of those). A query with FOLDER applied to a folder with a large number of tables and a heavy attribute can create a heavy load on the YT wizard.
+
+{% endnote %}
+
+**Examples:**
+
+```yql
+USE hahn;
+
+$table_paths = (
+ SELECT AGGREGATE_LIST(Path)
+ FROM FOLDER("my_folder", "schema;row_count")
+ WHERE
+ Type = "table" AND
+ Yson::GetLength(Attributes.schema) > 0 AND
+ Yson::LookupInt64(Attributes, "row_count") > 0
+);
+
+SELECT COUNT(*) FROM EACH($table_paths);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from.md
new file mode 100644
index 00000000000..65b9356c6ed
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from.md
@@ -0,0 +1,22 @@
+## FROM {#from}
+
+Data source for `SELECT`. The argument can accept the table name, the result of another `SELECT`, or a [named expression](../../expressions.md#named-nodes). Between `SELECT` and `FROM`, list the comma-separated column names from the source (or `*` to select all columns).
+
+{% if feature_mapreduce %}The table is searched by name in the database specified by the operator [USE](../../use.md).{% endif %}
+
+**Examples**
+
+```yql
+SELECT key FROM my_table;
+```
+
+```yql
+SELECT * FROM
+ (SELECT value FROM my_table);
+```
+
+```yql
+$table_name = "my_table";
+SELECT * FROM $table_name;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from_as_table.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from_as_table.md
new file mode 100644
index 00000000000..951b52805b6
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from_as_table.md
@@ -0,0 +1,17 @@
+## FROM AS_TABLE {#as-table}
+
+Accessing named expressions as tables using the `AS_TABLE` function.
+
+`AS_TABLE($variable)` lets you use the value of `$variable` as the data source for the query. In this case, the variable `$variable` must have the type `List<Struct<...>>`.
+
+**Example**
+
+```yql
+$data = AsList(
+ AsStruct(1u AS Key, "v1" AS Value),
+ AsStruct(2u AS Key, "v2" AS Value),
+ AsStruct(3u AS Key, "v3" AS Value));
+
+SELECT Key, Value FROM AS_TABLE($data);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from_select.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from_select.md
new file mode 100644
index 00000000000..386e5ca4291
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/from_select.md
@@ -0,0 +1,17 @@
+## FROM ... SELECT ... {#from-select}
+
+An inverted format, first specifying the data source and then the operation.
+
+**Examples**
+
+```yql
+FROM my_table SELECT key, value;
+```
+
+```yql
+FROM a_table AS a
+JOIN b_table AS b
+USING (key)
+SELECT *;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/functional_tables.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/functional_tables.md
new file mode 100644
index 00000000000..33db1d9a0ec
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/functional_tables.md
@@ -0,0 +1,114 @@
+## Accessing multiple tables in a single query {#concat} {#each} {#range} {#like} {#filter} {#regexp}
+
+Standard SQL uses [UNION ALL](#unionall) to execute a query across multiple tables and combine the results of two or more `SELECT` statements. This is not very convenient for the use case of running the same query on multiple tables (for example, if they contain data for different dates). To make this more convenient, in YQL `SELECT` statements, after `FROM`, you can specify not only a table or a subquery, but also call built-in functions letting you combine data from multiple tables.
+
+The following functions are defined for these purposes:
+
+```CONCAT(`table1`, `table2`, `table3` VIEW view_name, ...)``` combines all the tables listed in the arguments.
+
+```EACH($list_of_strings) or EACH($list_of_strings VIEW view_name)``` combines all tables whose names are listed in the list of strings. Optionally, you can pass multiple lists in separate arguments similar to `CONCAT`.
+
+```RANGE(`prefix`, `min`, `max`, `suffix`, `view`)``` combines a range of tables. Arguments:
+
+* The prefix is the folder to search tables in. It's specified without a trailing slash. This is the only required argument. If it's the only one specified, all tables in the folder are used.
+* min, max: These two arguments specify a range of table names included. The range is inclusive on both ends. If no range is specified, all tables in the prefix folder are used. The names of tables or folders located in the folder specified in prefix are lexicographically matched with the `[min, max]` range rather than concatenated, so make sure to specify the range without leading slashes.
+* suffix is the name of the table. It's expected without a leading slash. If no suffix is specified, then the `[min, max]` arguments specify a range of table names. If the suffix is specified, then the `[min, max]` arguments specify a range of folders hosting a table with the name specified in the suffix argument.
+
+```LIKE(`prefix`, `pattern`, `suffix`, `view`)``` and ```REGEXP(`prefix`, `pattern`, `suffix`, `view`)```: The pattern argument is specified in the format similar to the binary operators of the same name: [LIKE](../../expressions.md#like) and [REGEXP](../../expressions.md#regexp).
+
+```FILTER(`prefix`, `callable`, `suffix`, `view`)```: The `callable` argument must be a callable expression with the `(String)->Bool` signature that will be called for each table/subdirectory in the prefix folder. The query will only include those tables for which the callable value returned `true`. It is most convenient to use, as callable values, [lambda functions](../../expressions.md#lambda){% if yql == true %} or user-defined functions (UDF) written in [Python](../../../udf/python.md) or [JavaScript](../../../udf/javascript.md){% endif %}.
+
+{% note warning %}
+
+All of the above functions don't guarantee the order of the table union.
+
+The list of tables is calculated **before** executing the query. Therefore, the tables created during the query execution won't be included in the function results.
+
+{% endnote %}
+
+By default, the schemas of all the unioned tables are combined using the [UNION ALL](#unionall) rules. If you don't want to combine schemas, then you can use functions with the `_STRICT` suffix, for example `CONCAT_STRICT` or `RANGE_STRICT` that are totally similar to the original functions, but treat any difference in table schemas as an error.
+
+To specify a cluster of unioned tables, add it before the function name.
+
+All arguments of the functions described above can be declared separately using [named expressions](../../expressions.md#named-nodes). In this case, you can also use simple expressions in them by implicitly calling [EvaluateExpr](../../../builtins/basic.md#evaluate_expr_atom).
+
+To get the name of the source table from which you originally obtained each row, use [TablePath()](../../../builtins/basic.md#tablepath).
+
+**Examples:**
+
+```yql
+USE some_cluster;
+SELECT * FROM CONCAT(
+ `table1`,
+ `table2`,
+ `table3`);
+```
+
+```yql
+USE some_cluster;
+$indices = ListFromRange(1, 4);
+$tables = ListMap($indices, ($index) -> {
+ RETURN "table" || CAST($index AS String);
+});
+SELECT * FROM EACH($tables); -- Identical to the previous example
+```
+
+```yql
+USE some_cluster;
+SELECT * FROM RANGE(`my_folder`);
+```
+
+```yql
+SELECT * FROM some_cluster.RANGE( -- You can specify the cluster before the function name
+ `my_folder`,
+ `from_table`,
+ `to_table`);
+```
+
+```yql
+USE some_cluster;
+SELECT * FROM RANGE(
+ `my_folder`,
+ `from_folder`,
+ `to_folder`,
+ `my_table`);
+```
+
+```yql
+USE some_cluster;
+SELECT * FROM RANGE(
+ `my_folder`,
+ `from_table`,
+ `to_table`,
+ ``,
+ `my_view`);
+```
+
+```yql
+USE some_cluster;
+SELECT * FROM LIKE(
+ `my_folder`,
+ "2017-03-%"
+);
+```
+
+```yql
+USE some_cluster;
+SELECT * FROM REGEXP(
+ `my_folder`,
+ "2017-03-1[2-4]?"
+);
+```
+
+```yql
+$callable = ($table_name) -> {
+ return $table_name > "2017-03-13";
+};
+
+USE some_cluster;
+SELECT * FROM FILTER(
+ `my_folder`,
+ $callable
+);
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/limit_offset.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/limit_offset.md
new file mode 100644
index 00000000000..17116bb887d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/limit_offset.md
@@ -0,0 +1,23 @@
+## LIMIT and OFFSET {#limit-offset}
+
+`LIMIT`: limits the output to the specified number of rows. By default, the output is not restricted.
+
+`OFFSET`: specifies the offset from the beginning (in rows). By default, it's zero.
+
+**Examples**
+
+```yql
+SELECT key FROM my_table
+LIMIT 7;
+```
+
+```yql
+SELECT key FROM my_table
+LIMIT 7 OFFSET 3;
+```
+
+```yql
+SELECT key FROM my_table
+LIMIT 3, 7; -- equivalent to the previous example
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/order_by.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/order_by.md
new file mode 100644
index 00000000000..2390f02238d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/order_by.md
@@ -0,0 +1,23 @@
+## ORDER BY {#order-by}
+
+Sorting the `SELECT` result using a comma-separated list of sorting criteria. As a criteria, you can use a column value or an expression on columns. Ordering by column sequence number is not supported (`ORDER BY N`where `N` is a number).
+
+Each criteria can be followed by the sorting direction:
+
+- `ASC`: Sorting in the ascending order. Applied by default.
+- `DESC`: Sorting in the descending order.
+
+Multiple sorting criteria will be applied left-to-right.
+
+**Example**
+
+```yql
+SELECT key, string_column
+FROM my_table
+ORDER BY key DESC, LENGTH(string_column) ASC;
+```
+
+{% if feature_window_functions %}
+You can also use `ORDER BY` for [window functions](../../window.md).
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/sample.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/sample.md
new file mode 100644
index 00000000000..acb8988b0e2
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/sample.md
@@ -0,0 +1,42 @@
+## TABLESAMPLE and SAMPLE {#tablesample} {#sample}
+
+Building a random sample from the data source specified in `FROM`.
+
+`TABLESAMPLE` is part of the SQL standard and works as follows:
+
+* The operating mode is specified:
+ * `BERNOULLI` means "slowly, straightforwardly going through all the data, but in a truly random way".
+ * `SYSTEM` uses knowledge about the physical data storage of data to avoid full data scans, but somewhat sacrificing randomness of the sample.
+The data is split into sufficiently large blocks, and the whole data blocks are sampled. For applied calculations on sufficiently large tables, the result may well be consistent.
+* The size of the random sample is indicated as a percentage after the operating mode, in parentheses.
+* To manage the block size in the `SYSTEM` mode, use the `yt.SamplingIoBlockSize` pragma.
+* Optionally, it can be followed by the `REPEATABLE` keyword and an integer in parentheses to be used as a seed for a pseudorandom number generator.
+
+`SAMPLE` is a shorter alias without sophisticated settings and sample size specified as a fraction. It currently corresponds to the `BERNOULLI` mode.
+
+{% note info %}
+
+In the `BERNOULLI` mode, if the `REPEATABLE` keyword is added, the seed is mixed with the chunk ID for each chunk in the table. That's why sampling from different tables with the same content might produce different results.
+
+{% endnote %}
+
+**Examples:**
+
+```yql
+SELECT *
+FROM my_table
+TABLESAMPLE BERNOULLI(1.0) REPEATABLE(123); -- one percent of the table
+```
+
+```yql
+SELECT *
+FROM my_table
+TABLESAMPLE SYSTEM(1.0); -- about one percent of the table
+```
+
+```yql
+SELECT *
+FROM my_table
+SAMPLE 1.0 / 3; -- one-third of the table
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/secondary_index.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/secondary_index.md
new file mode 100644
index 00000000000..30da15826d8
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/secondary_index.md
@@ -0,0 +1,30 @@
+## VIEW (INDEX) {#secondary_index}
+
+To make a `SELECT` by secondary index statement, use the following:
+
+```yql
+SELECT *
+ FROM TableName VIEW IndexName
+ WHERE …
+```
+
+**Examples**
+
+* Select all the fields from the `series` table using the `views_index` index with the `views >=someValue` criteria:
+
+ ```yql
+ SELECT series_id, title, info, release_date, views, uploaded_user_id
+ FROM series VIEW views_index
+ WHERE views >= someValue
+ ```
+
+* [`JOIN`](../../join.md) the `series` and `users` tables on the `userName` field using the `users_index` and `name_index` indexes, respectively:
+
+ ```yql
+ SELECT t1.series_id, t1.title
+ FROM series VIEW users_index AS t1
+ INNER JOIN users VIEW name_index AS t2
+ ON t1.uploaded_user_id == t2.user_id
+ WHERE t2.name == userName;
+ ```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/temporary_table.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/temporary_table.md
new file mode 100644
index 00000000000..0117bfd0581
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/temporary_table.md
@@ -0,0 +1,34 @@
+## Explicitly created temporary (anonymous) tables {#temporary-tables}
+
+In complex multiphase queries, it can be useful to explicitly create a physical temporary table in order to manually affect the query process. To do this, you can use the table name starting with `@`. Such tables are called anonymous to distinguish them from temporary tables created by a YT operation.
+
+Each such name within the query is replaced, at execution time, by a globally unique path to a table in a temporary directory. Such temporary tables are automatically deleted upon completion of the query, following the same rules as implicitly created tables.
+
+This feature lets you ignore conflicts in paths to temporary tables between parallel operations, and also avoid deleting them explicitly when the query completes.
+
+**Examples:**
+
+```yql
+INSERT INTO @my_temp_table
+SELECT * FROM my_input_table ORDER BY value;
+
+COMMIT;
+
+SELECT * FROM @my_temp_table WHERE value = "123"
+UNION ALL
+SELECT * FROM @my_temp_table WHERE value = "456";
+```
+
+Temporary table names can use [named expressions](../../expressions.md#named-nodes):
+
+```yql
+$tmp_name = "my_temp_table";
+
+INSERT INTO @$tmp_name
+SELECT 1 AS one, 2 AS two, 3 AS three;
+
+COMMIT;
+
+SELECT * FROM @$tmp_name;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/union_all.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/union_all.md
new file mode 100644
index 00000000000..505dc1f1825
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/union_all.md
@@ -0,0 +1,42 @@
+## UNION ALL {#union-all}
+
+Concatenating results of multiple `SELECT` statements (or subqueries).
+
+Two `UNION ALL` modes are supported: by column names (the default mode) and by column positions (corresponds to the ANSI SQL standard and is enabled by the [PRAGMA](../../pragma.md#positionalunionall)).
+
+In the "by name" mode, the output of the resulting data schema uses the following rules:
+
+{% include [union all rules](union_all_rules.md) %}
+
+The order of output columns in this mode is equal to the largest common prefix of the order of inputs, followed by all other columns in the alphabetic order.
+If the largest common prefix is empty (for example, if the order isn't specified for one of the inputs), then the output order is undefined.
+
+In the "by position" mode, the output of the resulting data schema uses the following rules:
+
+* All inputs must have equal number of columns
+* The order of columns must be defined for all inputs
+* The names of the resulting columns must match the names of columns in the first table
+* The type of the resulting columns is output as a common (widest) type of input column types having the same positions
+
+The order of the output columns in this mode is the same as the order of columns in the first input.
+
+**Examples**
+
+```yql
+SELECT 1 AS x
+UNION ALL
+SELECT 2 AS y
+UNION ALL
+SELECT 3 AS z;
+```
+
+In the default mode, this query returns a selection with three columns x, y, and z. When `PRAGMA PositionalUnionAll;` is enabled, the selection only includes the x column.
+
+```yql
+PRAGMA PositionalUnionAll;
+
+SELECT 1 AS x, 2 as y
+UNION ALL
+SELECT * FROM AS_TABLE([<|x:3, y:4|>]); -- error: the order of columns in AS_TABLE is undefined
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/union_all_rules.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/union_all_rules.md
new file mode 100644
index 00000000000..7c41e08bf82
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/union_all_rules.md
@@ -0,0 +1,5 @@
+* The resulting table includes all columns that were found in at least one of the input tables.
+* If a column wasn't present in all the input tables, then it's automatically assigned the [optional data type](../../../types/optional.md) (that can accept `NULL`).
+* If a column in different input tables had different types, then the shared type (the broadest one) is output.
+* If a column in different input tables had a heterogeneous type, for example, string and numeric, an error is raised.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/view.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/view.md
new file mode 100644
index 00000000000..193e6d526b6
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/view.md
@@ -0,0 +1,23 @@
+## Data views (VIEW) {#view}
+
+YQL supports two types of data views:
+
+* Linked to specific tables.
+* Independent, that might use an arbitrary number of tables within the cluster.
+Both of the views are non-materialized. It means that they are substituted into the calculation graph at each use.
+
+Accessing a `VIEW`:
+
+* Views linked to a table require a special syntax: ```[cluster.]`path/to/table` VIEW view_name```.
+* Views that aren't linked to tables, look like regular tables from the user perspective.
+
+If the meta attributes of the table specify an automatic UDF call to convert raw data into a structured set of columns, you can access raw data using a special `raw` view like this: ```[cluster.]`path/to/table` VIEW raw```.
+
+**Examples:**
+
+```yql
+USE some_cluster;
+SELECT *
+FROM my_table VIEW my_view;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/where.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/where.md
new file mode 100644
index 00000000000..3c5e5bf18b8
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/where.md
@@ -0,0 +1,11 @@
+## WHERE {#where}
+
+Filtering rows in the `SELECT` result based on a condition.
+
+**Example**
+
+```yql
+SELECT key FROM my_table
+WHERE value > 0;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/with.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/with.md
new file mode 100644
index 00000000000..b99e65fd329
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/with.md
@@ -0,0 +1,43 @@
+## WITH
+
+It's set after the data source in `FROM` and is used for additional hints for tables. You can't use hints for subqueries and [named expressions](../../expressions.md#named-nodes).
+
+The following values are supported:
+
+* `INFER_SCHEMA`: Sets the flag for output of the table schema. The behavior is similar to the [yt.inferSchema pragma](../../pragma.md#inferschema), but for a specific data source and without the option to specify the number of rows to output.
+* `DIRECT_READ`: Suppresses certain optimizers and enforces accessing table contents as is. The behavior is similar to the debug [pragma DirectRead](../../pragma.md#debug), but for a specific data source.
+* `INLINE`: Hints that the table contents is small and you need to use its in-memory view to process the query. The actual size of the table is not controlled in this case, and if it's large, the query might fail with an out-of-memory error.
+* `UNORDERED`: Suppresses original table sorting.
+* `XLOCK`: Hints that you need to lock the table exclusively. It's useful when you read a table at the stage of processing the [query metaprogram](../../action.md), and then update its contents in the main query. Avoids data loss if an external process managed to change the table between executing a metaprogram phase and the main part of the query.
+* `SCHEMA` type: Hints that the specified table schema must be used entirely, ignoring the schema in the metadata.
+* `COLUMNS` type: Hints that the specified types should be used for columns whose names match the table's column names in the metadata, as well as which columns are additionally present in the table.
+* `IGNORETYPEV3`, `IGNORE_TYPE_V3`: Sets the flag to ignore type_v3 types in the table. The behavior is similar to the [yt.IgnoreTypeV3 pragma](../../pragma.md#ignoretypev3), but for a specific data source.
+
+When setting the `SCHEMA` and `COLUMNS` hints, the type must be a [structure](../../../types/containers.md).
+If you use the `SCHEMA` hint, then with the table functions [EACH](#each), [RANGE](#range), [LIKE](#like), [REGEXP](#regexp), [FILTER](#filter) you can use an empty list of tables that is treated as an empty table with columns defined in the `SCHEMA`.
+
+**Examples:**
+
+```yql
+SELECT key FROM my_table WITH INFER_SCHEMA;
+```
+
+```yql
+$s = (SELECT COUNT(*) FROM my_table WITH XLOCK);
+
+INSERT INTO my_table WITH TRUNCATE
+SELECT EvaluateExpr($s) AS a;
+```
+
+```yql
+SELECT key, value FROM my_table WITH SCHEMA Struct<key:String, value:Int32>;
+```
+
+```yql
+SELECT key, value FROM my_table WITH COLUMNS Struct<value:Int32?>;
+```
+
+```yql
+SELECT key, value FROM EACH($my_tables) WITH SCHEMA Struct<key:String, value:List<Int32>>;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/without.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/without.md
new file mode 100644
index 00000000000..f61e5e96259
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select/without.md
@@ -0,0 +1,16 @@
+## WITHOUT {#without}
+
+Excluding columns from the result of `SELECT *`.
+
+**Examples**
+
+```yql
+SELECT * WITHOUT foo, bar FROM my_table;
+```
+
+```yql
+PRAGMA simplecolumns;
+SELECT * WITHOUT t.foo FROM my_table AS t
+CROSS JOIN (SELECT 1 AS foo) AS v;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select_stream.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select_stream.md
new file mode 100644
index 00000000000..cf859ca4fab
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/select_stream.md
@@ -0,0 +1,49 @@
+# SELECT STREAM ... FROM
+
+To use RTMR streams, use the construct `SELECT STREAM` rather than `SELECT` used for regular tables in other systems. `FROM` is used to specify the data source. Usually, the argument in `FROM` is the name of the stream searched for in the cluster specified in [USE](../use.md), but you can also use the result of other `SELECT STREAM` (a subquery). You can also specify a stream using a [named expression](../expressions.md#named-nodes) containing a string.
+
+You can specify column names from the source (separated by commas) in your statements, between `SELECT STREAM` and `FROM`. The `*` special character in this position means "all columns".
+
+**Examples:**
+
+```yql
+SELECT STREAM key FROM my_stream;
+```
+
+```yql
+SELECT STREAM * FROM
+ (SELECT STREAM value FROM my_stream);
+```
+
+```yql
+$stream_name = "my_" || "stream";
+SELECT STREAM * FROM $stream_name;
+```
+
+## WHERE
+
+Filtering rows in the `SELECT STREAM` result based on a condition.
+
+**Examples:**
+
+```yql
+SELECT STREAM key FROM my_stream
+WHERE value > 0;
+```
+
+## UNION ALL
+
+Concatenating the results of multiple `SELECT STREAM` statements with their schemas combined by the following rules:
+
+{% include [union all rules](../_includes/select/union_all_rules.md) %}
+
+**Examples:**
+
+```yql
+SELECT STREAM x FROM my_stream_1
+UNION ALL
+SELECT STREAM y FROM my_stream_2
+UNION ALL
+SELECT STREAM z FROM my_stream_3
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/subquery.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/subquery.md
new file mode 100644
index 00000000000..f9e2f51a7aa
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/subquery.md
@@ -0,0 +1,202 @@
+# Subquery templates
+
+## DEFINE SUBQUERY {#define-subquery}
+
+`DEFINE SUBQUERY` lets you declare a subquery template that is a parameterizable block of several top-level expressions (statements), and then use it repeatedly in the `FROM` section of [SELECT](../select.md){% if feature_mapreduce %} statements or as input data in [PROCESS](../process.md)/[REDUCE](../reduce.md){% endif %} with parameters.
+As opposed to [actions](../action.md), the subquery template must end with the `SELECT`{% if feature_mapreduce %}/`PROCESS`/`REDUCE`{% endif %} statement whose result is the subquery's return value. Keep in mind that you can't use the top-level `SELECT`{% if feature_mapreduce %}/`PROCESS`/`REDUCE`{% endif %} statement and the modifying expressions (for example, `INSERT`) more than once.
+
+After `DEFINE SUBQUERY`, specify:
+
+1. [A named expression](expressions.md#named-nodes) that will be used to access the declared template further in the query.
+2. The round brackets contain a list of named expressions you can use to access parameters inside the subquery template.
+3. `AS` keyword.
+4. The list of top-level expressions.
+5. `END DEFINE` acts as a marker of the last expression inside the subquery template.
+
+One or more of the last subquery parameters can be marked with a question as optional: unless they haven't been specified when calling subquery, they will be assigned the `NULL` value.
+
+{% if feature_mapreduce %}
+
+{% note info %}
+
+In large queries, you can use separate files for action definition and include them to the main query using [EXPORT](../export_import.md#export) + [IMPORT](../export_import.md#import) so that instead of one long text you can have several logical parts that are easier to navigate. An important nuance: the `USE my_cluster;` directive in the import query doesn't affect behavior of actions declared in other subquery files.
+
+{% endnote %}
+
+{% endif %}
+
+Even if the list of parameters in the subquery template definition is empty, when using it in `FROM`, specify the parentheses `()`. This may help to limit the scope of named expressions used in only one subquery.
+
+{% if feature_mapreduce %}
+In some cases, instead of `DEFINE SUBQUERY` it's more convenient to use an equivalent [lambda function](../expressions.md#lambda).
+In this case, the lambda function must accept, as the first argument, the special object called `world` that passes dependencies to make certain PRAGMA or COMMIT statements visible at the query template's point of use. Also, make sure to pass this object as the first argument along with the other arguments (if any) to other query templates, if you use them in your lambda function.
+The return value of the lambda function must have the structure list type (output table) or a list of variants over a tuple of structures (multiple output tables). In the latter case, the following unpacking is usually used at the query template's point of use:
+
+```yql
+$out1, $out2 = PROCESS $mySubquery($myParam1, $myParam2);
+-- next we use $out1 and $out2 as separate tables.
+```
+
+{% endif %}
+
+**Examples**
+
+```yql
+DEFINE SUBQUERY $hello_world($name, $suffix?) AS
+ $name = $name ?? ($suffix ?? "world");
+ SELECT "Hello, " || $name || "!";
+END DEFINE;
+
+SELECT * FROM $hello_world(NULL); -- Hello, world!
+SELECT * FROM $hello_world("John"); -- Hello, John!
+SELECT * FROM $hello_world(NULL, "Earth"); -- Hello, Earth!
+```
+
+```yql
+DEFINE SUBQUERY $dup($x) AS
+ SELECT * FROM $x(1) -- apply the passed query template with one argument
+ UNION ALL
+ SELECT * FROM $x(2); -- ... and with other argument
+END DEFINE;
+
+DEFINE SUBQUERY $sub($n) AS
+ SELECT $n * 10;
+END DEFINE;
+
+SELECT * FROM $dup($sub); -- pass the query template $sub as a parameter
+-- Result:
+-- 10
+-- 20
+```
+
+```yql
+/* Hide the named expressions $a and $b inside a separate scope */
+DEFINE SUBQUERY $clean() AS
+ $a = 10;
+ $b = $a * $a;
+ SELECT $a AS a, $b AS b;
+END DEFINE;
+
+SELECT * FROM $clean(); -- a: 10, b: 100
+```
+
+{% if feature_mapreduce %}
+
+```yql
+USE hahn;
+
+DEFINE SUBQUERY $input() as
+ SELECT * FROM `home/yql/tutorial/users`;
+END DEFINE;
+
+DEFINE SUBQUERY $myProcess1($nestedQuery, $lambda) AS
+ PROCESS $nestedQuery() -- the parentheses () are mandatory here
+ USING $lambda(TableRow());
+END DEFINE;
+
+$myProcess2 = ($world, $nestedQuery, $lambda) -> {
+ -- If you use ListFlatMap or YQL::OrderedFlatMap, you get an Ordered YT Map operation
+ return YQL::FlatMap($nestedQuery($world), $lambda);
+};
+
+-- With such use, the implementations of $myProcess1 and $myProcess2 are identical
+SELECT * FROM $myProcess1($input, ($x) -> { RETURN AsList($x, $x) });
+SELECT * FROM $myProcess2($input, ($x) -> { RETURN AsList($x, $x) });
+```
+
+```yql
+USE hahn;
+
+DEFINE SUBQUERY $runPartition($table) AS
+ $paritionByAge = ($row) -> {
+ $recordType = TypeOf($row);
+ $varType = VariantType(TupleType($recordType, $recordType));
+ RETURN If($row.age % 2 == 0,
+ Variant($row, "0", $varType),
+ Variant($row, "1", $varType),
+ );
+ };
+
+ PROCESS $table USING $paritionByAge(TableRow());
+END DEFINE;
+
+-- Unpacking two results
+$i, $j = (PROCESS $runPartition("home/yql/tutorial/users"));
+
+SELECT * FROM $i;
+
+SELECT * FROM $j;
+```
+
+{% endif %}
+
+## Combining the subquery templates: SubqueryExtend, SubqueryUnionAll, SubqueryMerge, SubqueryUnionMerge {#subquery-extend} {#subquery-unionall} {#subquery-merge} {#subquery-unionmerge}
+
+These functions combine the results of one or more subquery templates passed by arguments. The number of parameters in such subquery templates must be the same.
+
+* `SubqueryExtend` requires matching of subquery schemas.
+* `SubqueryUnionAll` follows the same rules as [ListUnionAll](../../builtins/list.md#ListUnionAll).
+* `SubqueryMerge` uses the same constraints as `SubqueryExtend` and also outputs a sorted result if all subqueries have the same sort order.
+* `SubqueryUnionMerge` uses the same constraints as `SubqueryUnionAll` and also outputs a sorted result if all subqueries have the same sort order.
+
+**Examples:**
+
+```yql
+DEFINE SUBQUERY $sub1() as
+ SELECT 1 as x;
+END DEFINE;
+
+DEFINE SUBQUERY $sub2() as
+ SELECT 2 as x;
+END DEFINE;
+
+$s = SubqueryExtend($sub1,$sub2);
+PROCESS $s();
+```
+
+## Combining subquery templates after substituting list items: SubqueryExtendFor, SubqueryUnionAllFor, SubqueryMergeFor, SubqueryUnionMergeFor {#subquery-extend-for} {#subquery-unionall-for} {#subquery-merge-for} {#subquery-unionmerge-for}
+
+The functions take the following arguments:
+
+* A non-empty list of values.
+* A subquery template that must have exactly one parameter.
+
+They substitute each item from the list into the subquery template as a parameter and then combine the obtained subqueries.
+
+* `SubqueryExtendFor` requires matching of subquery schemas.
+* `SubqueryUnionAllFor` follows the same rules as [ListUnionAll](../../builtins/list.md#ListUnionAll).
+* `SubqueryMergeFor` uses the same constraints as `SubqueryExtendFor` and also outputs a sorted result if all subqueries have the same sort order.
+* `SubqueryUnionMergeFor` uses the same constraints as `SubqueryUnionAllFor` and also outputs a sorted result if all subqueries have the same sort order.
+
+**Examples:**
+
+```yql
+DEFINE SUBQUERY $sub($i) as
+ SELECT $i as x;
+END DEFINE;
+
+$s = SubqueryExtendFor([1,2,3],$sub);
+PROCESS $s();
+```
+
+## Adding sorting to the SubqueryOrderBy template or indicating the presence of this SubqueryAssumeOrderBy
+
+The functions take the following arguments:
+
+* A subquery template without parameters.
+* A list of pairs (string indicating the column name and Boolean value: True for sorting in ascending order or False for sorting in descending order).
+
+And they build a new query template without parameters where sorting is performed or a comment on the use of sorting is added to the result. To use the resulting query template, call the `PROCESS` function, since, when using a `SELECT`, sorting is ignored.
+
+**Examples:**
+
+```yql
+DEFINE SUBQUERY $sub() as
+ SELECT * FROM (VALUES (1,'c'), (1,'a'), (3,'b')) AS a(x,y);
+end define;
+
+$sub2 = SubqueryOrderBy($sub, [('x',false), ('y',true)]);
+
+PROCESS $sub2();
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/update.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/update.md
new file mode 100644
index 00000000000..92a724fcd99
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/update.md
@@ -0,0 +1,38 @@
+# UPDATE
+
+Updates the data in the table.{% if feature_mapreduce %} The table is searched by name in the database specified by the [USE](../use.md) operator.{% endif %} After the `SET` keyword, enter the columns where you want to update values and the new values themselves. The list of rows is defined by the `WHERE` clause. If `WHERE` is omitted, the updates are applied to all the rows of the table.
+
+`UPDATE` can't change the value of `PRIMARY_KEY`.
+
+{% note info %}
+
+The table state changes can't be tracked within a single transaction. If the table has already been changed, use [`UPDATE ON`](#update-on) to update the data within the same transaction.
+
+{% endnote %}
+
+**Example**
+
+```sql
+UPDATE my_table
+SET Value1 = YQL::ToString(Value2 + 1), Value2 = Value2 - 1
+WHERE Key1 > 1;
+```
+
+## UPDATE ON {#update-on}
+
+Used to update the data within a same transaction, if the table has already been changed.
+
+**Example**
+
+```sql
+$to_update = (
+ SELECT Key, SubKey, "Updated" AS Value FROM my_table
+ WHERE Key = 1
+);
+
+SELECT * FROM my_table;
+
+UPDATE my_table ON
+SELECT * FROM $to_update;
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/upsert_into.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/upsert_into.md
new file mode 100644
index 00000000000..53b3c767f16
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/upsert_into.md
@@ -0,0 +1,27 @@
+# UPSERT INTO
+
+Adds or updates multiple rows in a table based on primary key matching. Missing rows are added. For the existing rows, the values of the specified columns are updated, but the values of the other columns are preserved.
+
+{% if feature_mapreduce %} The table is searched by name in the database specified by the [USE](../use.md) operator.{% endif %}
+
+{% if feature_replace %}
+`UPSERT` and [`REPLACE`](../replace_into.md) are data modification operations that don't require a prefetch and run faster and cheaper than other operations because of that.
+{% else %}
+`UPSERT` is the only data modification operation that doesn't require prefetching and runs faster and cheaper than other operations because of that.
+{% endif %}
+
+Column mapping when using `UPSERT INTO ... SELECT` is done by names. Use `AS` to fetch a column with the desired name in `SELECT`.
+
+**Examples**
+
+```yql
+UPSERT INTO my_table
+SELECT pk_column, data_column1, col24 as data_column3 FROM other_table
+```
+
+```yql
+UPSERT INTO my_table ( pk_column1, pk_column2, data_column2, data_column5 )
+VALUES ( 1, 10, 'Some text', Date('2021-10-07')),
+ ( 2, 10, 'Some text', Date('2021-10-08'))
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/use.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/use.md
new file mode 100644
index 00000000000..2cf4f09d1e8
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/use.md
@@ -0,0 +1,24 @@
+# USE
+
+Specifying the "database". As a rule, one of the {{ backend_name }} clusters is used as a database. This database will be used by default to search for tables whenever the database hasn't been specified explicitly.
+
+If the query doesn't include `USE`, then the cluster must be specified at the beginning of the table path in the format ``` cluster.`path/to/table` ```, for example ``` hahn.`home/yql/test` ```. Backticks are used to automatically escape special characters (in this case, slashes).
+
+Usually the cluster name is specified explicitly, but you can use an expression for it. For example, this will let you use the parameters declared by [DECLARE](../declare.md).
+In this case, `USE` must have the notation ```USE yt:$cluster_name```, where `$cluster_name` is the [named expression](../expressions.md#named-nodes) of the `String` type.
+Alternatively, you can specify the cluster right at the beginning of the table path in the format ``` yt:$cluster_name.`path/to/table` ```.
+
+As far as `USE` is concerned, you can add it inside [actions](../action.md){% if feature_subquery %} or [subquery templates](../subquery.md){% endif %}. The value of the current cluster is inherited by declarations of nested actions{% if feature_subquery %} or subqueries{% endif %}. The scope of `USE` is terminated at the end of the action{% if feature_subquery %} or {% endif %} subquery template where it has been declared.
+
+**Examples:**
+
+```yql
+USE {{ example_cluster }};
+```
+
+{% note info %}
+
+`USE` **doesn't** guarantee that the query will be executed against the specified cluster. The query might be executed against other cluster if it doesn't use any input data (for example, `USE foo; SELECT 2 + 2;` ) or if the full path to the table on other cluster has been specified (for example, `USE foo; SELECT * FROM bar.``path/to/table``;`).
+
+{% endnote %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/values.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/values.md
new file mode 100644
index 00000000000..eb9682c39ae
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/values.md
@@ -0,0 +1,45 @@
+# Basic VALUES syntax in YQL
+
+## VALUES as a top-level operator
+
+It lets you create a table from specified values. For example, this statement creates a table of k columns and n rows:
+
+```yql
+VALUES (expr_11, expr_12, ..., expr_1k),
+ (expr_21, expr_22, ..., expr_2k),
+ ....
+ (expr_n1, expr_n2, ..., expr_nk);
+```
+
+This statement is totally equivalent to the following one:
+
+```yql
+SELECT expr_11, expr_12, ..., expr_1k UNION ALL
+SELECT expr_21, expr_22, ..., expr_2k UNION ALL
+....
+SELECT expr_n1, expr_n2, ..., expr_nk;
+```
+
+**Example:**
+
+```yql
+VALUES (1,2), (3,4);
+```
+
+## VALUES after FROM
+
+VALUES can also be used in a subquery, after FROM. For example, the following two queries are equivalent:
+
+```yql
+VALUES (1,2), (3,4);
+SELECT * FROM (VALUES (1,2), (3,4));
+```
+
+In all the examples above, column names are assigned by YQL and have the format `column0 ... columnN`. To assign arbitrary column names, you can use the following construct:
+
+```yql
+SELECT * FROM (VALUES (1,2), (3,4)) as t(x,y);
+```
+
+In this case, the columns will get the names `x`, `y`.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/window.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/window.md
new file mode 100644
index 00000000000..f406bebf297
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/_includes/window.md
@@ -0,0 +1,157 @@
+# OVER, PARTITION BY, and WINDOW
+
+Window functions were introduced in the SQL:2003 standard and expanded in the SQL:2011 standard. They let you run calculations on a set of table rows that are related to the current row in some way.
+
+Unlike [aggregate functions](../../builtins/aggregation.md), window functions don't group rows into one output row: the number of rows in the resulting table is always the same as in the source table.
+
+If a query contains both aggregate and window functions, grouping is performed and aggregate function values are calculated first. The calculated values of aggregate functions can be used as window function arguments (but not the other way around).
+
+## Syntax {#syntax}
+
+General syntax for calling a window function is as follows
+
+```
+function_name([expression [, expression ...]]) OVER (window_definition)
+or
+function_name([expression [, expression ...]]) OVER window_name
+```
+
+Here, `window_name` (_window name_) is an arbitrary ID that is unique within the query and `expression` is an arbitrary expression that contains no window function calls.
+
+In the query, each window name must be mapped to the _window definition_ (`window_definition`):
+
+```
+SELECT
+ F0(...) OVER (window_definition_0),
+ F1(...) OVER w1,
+ F2(...) OVER w2,
+ ...
+FROM my_table
+WINDOW
+ w1 AS (window_definition_1),
+ ...
+ w2 AS (window_definition_2)
+;
+```
+
+Here, the `window_definition` is written as
+
+```
+[ PARTITION BY (expression AS column_identifier | column_identifier) [, ...] ]
+[ ORDER BY expression [ASC | DESC] ]
+[ frame_definition ]
+```
+
+You can set an optional *frame definition* (`frame_definition`) one of two ways:
+
+* ```ROWS frame_begin```
+* ```ROWS BETWEEN frame_begin AND frame_end```
+
+*The frame start* (`frame_begin`) and *frame end* (`frame_end`) are set one of the following ways:
+
+* ```UNBOUNDED PRECEDING```
+* ```offset PRECEDING```
+* ```CURRENT ROW```
+* ```offset FOLLOWING```
+* ```UNBOUNDED FOLLOWING```
+
+Here, the *frame* `offset` is a non-negative numeric literal. If the frame end isn't set, the `CURRENT ROW` is assumed.
+
+There should be no window function calls in any of the expressions inside the window definition.
+
+## Calculation algorithm
+
+### Partitioning {#partition}
+
+If `PARTITION BY` is set, the source table rows are grouped into _partitions_, which are then handled independently of each other.
+If `PARTITION BY` isn't set, all rows in the source table are put in the same partition. If `ORDER BY` is set, it determines the order of rows in a partition.
+Both in `PARTITION BY` and [GROUP BY](../group_by.md) you can use aliases and [SessionWindow](../group_by.md#session-window).
+
+If `ORDER BY` is omitted, the order of rows in the partition is undefined.
+
+### Frame {#frame}
+
+The `frame_definition` specifies a set of partition rows that fall into the *window frame* associated with the current row.
+
+In `ROWS` mode (the only one that YQL currently supports), the window frame contains rows with the specified offsets relative to the current row in the partition.
+
+ * For example, if `ROWS BETWEEN 3 PRECEDING AND 5 FOLLOWING` is used, the window frame contains 3 rows preceding the current one, the current row, and 5 rows following it.
+
+The set of rows in the window frame may change depending on which row is the current one.
+
+ * For example, for the first row in the partition, the `ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING` window frame will have no rows.
+
+Setting `UNBOUNDED PRECEDING` as the frame start means "from the first partition row" and `UNBOUNDED FOLLOWING` as the frame end — "up to the last partition row". Setting `CURRENT ROW` means "from/to the current row".
+
+If no `frame_definition` is specified, a set of rows to be included in the window frame depends on whether there is `ORDER BY` in the `window_definition`.
+Namely, if there is `ORDER BY`, then `ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW` is implicitly assumed. If none, then `ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING`.
+
+Further, depending on the specific window function, it's calculated either based on the set of rows in the partition or the set of rows in the window frame.
+
+[List of available window functions](../../builtins/window.md)
+
+**Examples:**
+
+```sql
+SELECT
+ COUNT(*) OVER w AS rows_count_in_window,
+ some_other_value -- access the current row
+FROM `my_table`
+WINDOW w AS (
+ PARTITION BY partition_key_column
+ ORDER BY int_column
+);
+```
+
+```sql
+SELECT
+ LAG(my_column, 2) OVER w AS row_before_previous_one
+FROM `my_table`
+WINDOW w AS (
+ PARTITION BY partition_key_column
+);
+```
+
+```yql
+SELECT
+ -- AVG (like all aggregate functions used as window functions)
+ -- is calculated on the window frame
+ AVG(some_value) OVER w AS avg_of_prev_current_next,
+ some_other_value -- access the current row
+FROM my_table
+WINDOW w AS (
+ PARTITION BY partition_key_column
+ ORDER BY int_column
+ ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
+);
+```
+
+```yql
+SELECT
+ -- LAG doesn't depend on the window frame position
+ LAG(my_column, 2) OVER w AS row_before_previous_one
+FROM my_table
+WINDOW w AS (
+ PARTITION BY partition_key_column
+ ORDER BY my_column
+);
+```
+
+## Implementation specifics
+
+* Functions calculated on the `ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING` or `ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW` window frame are implemented efficiently (do not require additional memory and their computation runs on a partition in O(partition size) time).
+
+* For the `ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING` window frame, you can choose the execution strategy in RAM by specifying the `COMPACT` hint after the `PARTITION` keyword.
+
+ For example, `PARTITION COMPACT BY key` or `PARTITION COMPACT BY ()` (if `PARTITION BY` was missing initially).
+
+ If the `COMPACT` hint is specified, this requires additional memory equal to O(partition size), but then no extra `JOIN` operation is made.
+
+* If the window frame doesn't start with `UNBOUNDED PRECEDING`, calculating window functions on this window requires additional memory equal to O(the maximum number of rows from the window boundaries to the current row), while the computation time is equal to O(number_of_partition_rows * window_size).
+
+* For the window frame starting with `UNBOUNDED PRECEDING` and ending with `N`, where `N` is neither `CURRENT ROW` nor `UNBOUNDED FOLLOWING`, additional memory equal to O(N) is required and the computation time is equal to O(N * number_of_partition_rows).
+
+* The `LEAD(expr, N)` and `LAG(expr, N)` functions always require O(N) of RAM.
+
+Given the above, a query with `ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING` should, if possible, be changed to `ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW` by reversing the `ORDER BY` sorting order.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/action.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/action.md
new file mode 100644
index 00000000000..2ddce04ead2
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/action.md
@@ -0,0 +1,11 @@
+# ACTION
+
+{% include [x](_includes/action/define_do.md) %}
+
+{% include [x](_includes/action/begin.md) %}
+
+{% if feature_mapreduce %}
+
+ {% include [x](_includes/action/evaluate.md) %}
+
+{% endif %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/alter_table.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/alter_table.md
new file mode 100644
index 00000000000..a6134ef7ede
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/alter_table.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/alter_table.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/create_table.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/create_table.md
new file mode 100644
index 00000000000..afc4f96ab9e
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/create_table.md
@@ -0,0 +1 @@
+{% include [x](_includes/create_table.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/declare.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/declare.md
new file mode 100644
index 00000000000..c3b29c2de89
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/declare.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/declare/general.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/delete.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/delete.md
new file mode 100644
index 00000000000..152f774f9f8
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/delete.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/delete.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/discard.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/discard.md
new file mode 100644
index 00000000000..e00213ace76
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/discard.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/discard.md) %} \ No newline at end of file
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/drop_table.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/drop_table.md
new file mode 100644
index 00000000000..d708dc5d9ef
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/drop_table.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/drop_table.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/export_import.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/export_import.md
new file mode 100644
index 00000000000..874d843a7b7
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/export_import.md
@@ -0,0 +1,2 @@
+{% include [x](_includes/export_import.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/expressions.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/expressions.md
new file mode 100644
index 00000000000..e3bce9d7ddd
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/expressions.md
@@ -0,0 +1,32 @@
+# Expressions
+
+{% include [x](_includes/expressions/concatenation.md) %}
+
+{% include [x](_includes/expressions/check-match.md) %}
+
+{% include [x](_includes/expressions/operators.md) %}
+
+{% include [x](_includes/expressions/is-null.md) %}
+
+{% include [x](_includes/expressions/is-distinct-from.md) %}
+
+{% include [x](_includes/expressions/between.md) %}
+
+{% include [x](_includes/expressions/in.md) %}
+
+{% include [x](_includes/expressions/as.md) %}
+
+{% include [x](_includes/expressions/cast.md) %}
+
+{% include [x](_includes/expressions/bitcast.md) %}
+
+{% include [x](_includes/expressions/case.md) %}
+
+{% include [x](_includes/expressions/named-nodes.md) %}
+
+{% include [x](_includes/expressions/tables.md) %}
+
+{% include [x](_includes/expressions/lambda.md) %}
+
+{% include [x](_includes/expressions/items-access.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/flatten.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/flatten.md
new file mode 100644
index 00000000000..4068bae5b7e
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/flatten.md
@@ -0,0 +1,7 @@
+{% include [x](_includes/flatten/flatten_by.md) %}
+
+{% include [x](_includes/flatten/flatten_type_by.md) %}
+
+{% include [x](_includes/flatten/flatten_other_db.md) %}
+
+{% include [x](_includes/flatten/flatten_columns.md) %} \ No newline at end of file
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/group_by.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/group_by.md
new file mode 100644
index 00000000000..b68596578bb
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/group_by.md
@@ -0,0 +1,27 @@
+{% if select_command == "SELECT STREAM" %}
+
+ {% include [x](_includes/group_by/general_stream.md) %}
+
+ {% include [x](_includes/group_by/having_stream.md) %}
+
+{% else %}
+
+{% include [x](_includes/group_by/general.md) %}
+
+{% include [x](_includes/group_by/session_window.md) %}
+
+{% if feature_group_by_rollup_cube %}
+
+ {% include [x](_includes/group_by/rollup_cube_sets.md) %}
+
+{% endif %}
+
+{% include [x](_includes/group_by/distinct.md) %}
+
+{% include [x](_includes/group_by/compact.md) %}
+
+{% include [x](_includes/group_by/having.md) %}
+
+{% endif %}
+
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/index.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/index.md
new file mode 100644
index 00000000000..3594e5b469a
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/index.md
@@ -0,0 +1,56 @@
+# List of articles on YQL syntax
+
+* [Lexical structure](lexer.md)
+* [Expressions](expressions.md)
+{% if feature_mapreduce %}
+* [USE](use.md)
+{% endif %}
+* [SELECT](select.md)
+* [VALUES](values.md)
+{% if select_command == "SELECT STREAM" %}
+* [SELECT STREAM](select_stream.md)
+{% endif %}
+* [CREATE TABLE](create_table.md)
+* [DROP TABLE](drop_table.md)
+* [INSERT](insert_into.md)
+{% if feature_map_tables %}
+* [UPDATE](update.md)
+* [DELETE](delete.md)
+{% endif %}
+{% if feature_replace %}
+* [REPLACE](replace_into.md)
+{% endif %}
+{% if feature_upsert %}
+* [UPSERT](upsert_into.md)
+{% endif %}
+* [GROUP BY](group_by.md)
+{% if feature_join %}
+* [JOIN](join.md)
+{% endif %}
+{% if feature_window_functions %}
+* [WINDOW](window.md)
+{% endif %}
+* [FLATTEN](flatten.md)
+* [ACTION](action.md)
+{% if feature_mapreduce and process_command == "PROCESS" %}
+* [SUBQUERY](subquery.md)
+{% endif %}
+* [DISCARD](discard.md)
+* [INTO RESULT](into_result.md)
+{% if feature_mapreduce %}
+{% if process_command == "PROCESS" %}
+* [PROCESS](process.md)
+{% endif %}
+{% if process_command == "PROCESS STREAM" %}
+* [PROCESS STREAM](process.md)
+{% endif %}
+{% if reduce_command == "REDUCE" %}
+* [REDUCE](reduce.md)
+{% endif %}
+{% endif %}
+* [PRAGMA](pragma.md)
+* [DECLARE](declare.md)
+{% if feature_mapreduce %}
+* [EXPORT and IMPORT](export_import.md)
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/insert_into.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/insert_into.md
new file mode 100644
index 00000000000..54126433c92
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/insert_into.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/insert_into.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/into_result.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/into_result.md
new file mode 100644
index 00000000000..a4fa2e247ef
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/into_result.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/into_result.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/join.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/join.md
new file mode 100644
index 00000000000..cbef5bb3693
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/join.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/join.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/lexer.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/lexer.md
new file mode 100644
index 00000000000..1b753402103
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/lexer.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/lexer.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/not_yet_supported.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/not_yet_supported.md
new file mode 100644
index 00000000000..4022cb3aeac
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/not_yet_supported.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/not_yet_supported.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/pragma.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/pragma.md
new file mode 100644
index 00000000000..5249455c7d3
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/pragma.md
@@ -0,0 +1,13 @@
+# PRAGMA
+
+{% include [x](_includes/pragma/definition.md) %}
+
+{% include [x](_includes/pragma/global.md) %}
+
+{% include [x](_includes/pragma/yson.md) %}
+
+{% include [x](_includes/pragma/files.md) %}
+
+{% include [x](_includes/pragma/ydb.md) %}
+
+{% include [x](_includes/pragma/debug.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/process.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/process.md
new file mode 100644
index 00000000000..7ea4f9e2b30
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/process.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/process.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/reduce.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/reduce.md
new file mode 100644
index 00000000000..5885c8354c6
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/reduce.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/reduce.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/replace_into.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/replace_into.md
new file mode 100644
index 00000000000..96d50060b27
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/replace_into.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/replace_into.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/select.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/select.md
new file mode 100644
index 00000000000..ed23eefd909
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/select.md
@@ -0,0 +1,50 @@
+# SELECT syntax
+
+<!-- File split by includable blocks as part of YQL docs preparation for YQL/YDB opensource -->
+
+{% include [x](_includes/select/calc.md) %}
+
+{% include [x](_includes/select/from.md) %}
+
+{% include [x](_includes/select/secondary_index.md) %}
+
+{% include [x](_includes/select/with.md) %}
+
+{% include [x](_includes/select/where.md) %}
+
+{% include [x](_includes/select/order_by.md) %}
+
+{% include [x](_includes/select/limit_offset.md) %}
+
+{% include [x](_includes/select/assume_order_by.md) %}
+
+{% include [x](_includes/select/sample.md) %}
+
+{% include [x](_includes/select/distinct.md) %}
+
+{% include [x](_includes/select/execution.md) %}
+
+{% include [x](_includes/select/column_order.md) %}
+
+{% include [x](_includes/select/union_all.md) %}
+
+{% include [x](_includes/select/commit.md) %}
+
+{% if feature_bulk_tables %}
+
+ {% include [x](_includes/select/functional_tables.md) %}
+
+ {% include [x](_includes/select/folder.md) %}
+
+{% endif %}
+
+{% include [x](_includes/select/without.md) %}
+
+{% include [x](_includes/select/from_select.md) %}
+
+{% include [x](_includes/select/view.md) %}
+
+{% include [x](_includes/select/temporary_table.md) %}
+
+{% include [x](_includes/select/from_as_table.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/select_stream.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/select_stream.md
new file mode 100644
index 00000000000..40dd9100bac
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/select_stream.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/select_stream.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/subquery.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/subquery.md
new file mode 100644
index 00000000000..75c6ac92a80
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/subquery.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/subquery.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/toc_i.yaml b/ydb/docs/en/core/yql/reference/yql-core/syntax/toc_i.yaml
new file mode 100644
index 00000000000..db6c5392e89
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/toc_i.yaml
@@ -0,0 +1,31 @@
+items:
+- { name: Overview, href: index.md }
+- { name: Lexical structure, href: lexer.md }
+- { name: Expressions, href: expressions.md }
+- { name: ACTION, href: action.md }
+- { name: ALTER TABLE, href: alter_table.md, when: feature_map_tables }
+- { name: CREATE TABLE, href: create_table.md }
+- { name: DECLARE, href: declare.md }
+- { name: DELETE, href: delete.md, when: feature_map_tables }
+- { name: DISCARD, href: discard.md }
+- { name: DROP TABLE, href: drop_table.md }
+- { name: GROUP BY, href: group_by.md }
+- { name: EXPORT and IMPORT, href: export_import.md, when: feature_mapreduce }
+- { name: FLATTEN, href: flatten.md }
+- { name: INSERT, href: insert_into.md }
+- { name: INTO RESULT, href: into_result.md }
+- { name: JOIN, href: join.md, when: feature_join }
+- { name: PRAGMA, href: pragma.md }
+- { name: PROCESS STREAM, href: process.md, when: feature_mapreduce and process_command == "PROCESS STREAM" }
+- { name: PROCESS, href: process.md, when: feature_mapreduce and process_command == "PROCESS" }
+- { name: REDUCE, href: reduce.md, when: feature_mapreduce and reduce_command == "REDUCE" }
+- { name: REPLACE, href: replace_into.md, when: feature_replace }
+- { name: SELECT, href: select.md }
+- { name: SELECT STREAM, href: select_stream.md, when: feature_mapreduce and process_command == "PROCESS STREAM" }
+- { name: SUBQUERY, href: subquery.md, when: feature_subquery }
+- { name: UPDATE, href: update.md, when: feature_map_tables }
+- { name: UPSERT, href: upsert_into.md, when: feature_upsert }
+- { name: USE, href: use.md, when: feature_mapreduce }
+- { name: VALUES, href: values.md }
+- { name: WINDOW, href: window.md, when: feature_window_functions }
+- { name: Unsupported statements, href: not_yet_supported.md }
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/update.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/update.md
new file mode 100644
index 00000000000..6b2cb43b7bb
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/update.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/update.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/upsert_into.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/upsert_into.md
new file mode 100644
index 00000000000..7ca3636a735
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/upsert_into.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/upsert_into.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/use.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/use.md
new file mode 100644
index 00000000000..c567fc6b949
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/use.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/use.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/values.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/values.md
new file mode 100644
index 00000000000..e64464f7323
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/values.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/values.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/syntax/window.md b/ydb/docs/en/core/yql/reference/yql-core/syntax/window.md
new file mode 100644
index 00000000000..3eb79a7b960
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/syntax/window.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/window.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/toc_m.yaml b/ydb/docs/en/core/yql/reference/yql-core/toc_m.yaml
new file mode 100644
index 00000000000..35ad87ba4d8
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/toc_m.yaml
@@ -0,0 +1,2 @@
+items:
+- include: { mode: merge, path: yql-product/toc_product.yaml }
diff --git a/ydb/docs/en/core/yql/reference/yql-core/toc_product.yaml b/ydb/docs/en/core/yql/reference/yql-core/toc_product.yaml
new file mode 100644
index 00000000000..9781b330eea
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/toc_product.yaml
@@ -0,0 +1,9 @@
+title: YQL over {{ backend_name }}
+# href: index.md
+items:
+- name: Data types
+ include: { mode: link, path: types/toc_i.yaml }
+- name: Syntax
+ include: { mode: link, path: syntax/toc_i.yaml }
+- name: Built-in functions
+ include: { mode: link, path: builtins/toc_i.yaml }
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/cast.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/cast.md
new file mode 100644
index 00000000000..b89466dfc80
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/cast.md
@@ -0,0 +1,71 @@
+# Rules for type casting using the operator [CAST](../../syntax/expressions.md#cast)
+
+## Rules for casting primitive data types.
+
+* When casting primitive data types, some of the source information may be discarded unless contained in the target type. For example:
+ * The `Float`/`Double` fractional part, when casting to integer types.
+ * The `Datetime`/`Timestamp` time, when casting to `Date`.
+ * The timezone, when casting from timezone types to date/time types without a timezone.
+* If, in a certain combination of the source and target type, casting can't be performed for all possible values of the source type, then, if the casting fails, `CAST` returns `NULL`. In such cases, one `Optional` level is added to the return value type, unless already present. For example, the constructs: `CAST("3.14" AS Float?)` and `CAST("3.14" AS Float)` are fully equivalent and return `Float?`.
+* If casting is possible for all values of the source type, then adding '?' works the same way as`Just` on top: `CAST(3.14 AS Utf8?)` is same as `Just(CAST(3.14 AS Utf8))`
+All combinations of primitive data types for which `CAST` can be used are described [here](../primitive.md).
+
+## Casting rules for containers.
+
+### Rules for Optional
+
+* If a higher `Optional` level is set for the target type than for the source type, it's same as adding `Just` on top of `CAST` with a lower `Optional` level.
+* If the source type has a higher level of `Optional` for the source type, then `NULL` at any level higher than the target level results in `NULL`.
+* At equal levels of `Optional`, the `NULL` value preserves the same level.
+
+```yql
+SELECT
+ CAST(1 AS Int32?), -- is equivalent to Just(1)
+ CAST(Just(2/1) AS Float??), -- [2]
+ CAST(Just(3/0) AS Float??) IS NULL; -- false: the result is Just(NULL)
+```
+
+### Rules for List/Dict
+
+* To create a list, `CAST` is applied to each item in the source list to cast it to the target type.
+* If the target item type is non-optional and `CAST` on the item might fail, then such casting is discarded. In this case, the resulting list might be shorter or even empty if every casting failed.
+* For dictionaries, the casting is totally similar to lists, with `CAST` being applied to keys and values.
+
+```yql
+SELECT
+ CAST([-1, 0, 1] AS List<Uint8?>), -- [null, 0, 1]
+ CAST(["3.14", "bad", "42"] AS List<Float>), -- [3.14, 42]
+
+ CAST({-1:3.14, 7:1.6} AS Dict<Uint8, Utf8>), -- {7: "1.6"}
+ CAST({-1:3.14, 7:1.6} AS Dict<Uint8?, Utf8>); -- {7: "1.6", null:"3.14"}
+```
+
+### Rules for Struct/Tuple
+
+* A structure or tuple is created by applying `CAST` to each item of the source type to cast it to an item with the same name or target type index.
+* If some field is missing in the target type, it's simply discarded.
+* If some field is missing in the source value type, then it can be added only if it's optional and accepts the `NULL` value.
+* If some field is non-optional in the target type, but its casting might fail, then `CAST` adds Optional to the structure or tuple level and might return `NULL` for the entire result.
+
+```yql
+SELECT
+ CAST((-1, 0, 1) AS Tuple<Uint16?, Uint16?, Utf8>), -- (null, 0, "1")
+ CAST((-2, 0) AS Tuple<Uint16, Utf8>), -- null
+ CAST((3, 4) AS Tuple<Uint16, String>), -- (3, "4"): the type is Tuple<Uint16, String>?
+ CAST(("4",) AS Tuple<Uint16, String?>), -- (4, null)
+ CAST((5, 6, null) AS Tuple<Uint8?>); -- (5,): the items were removed.
+
+SELECT -- One field was removed and one field was added: ("three":null, "two": "42")
+ CAST(<|one:"8912", two:42|> AS Struct<two:Utf8, three:Date?>);
+```
+
+### Rules for Variant
+
+* A variant with a specific name or index is cast to a variant with the same name or index.
+* If casting of a variant might fail and the type of this variant is non-optional, then `CAST` adds Optional to the top level and can return `NULL`.
+* If some variant is missing in the target type, then `CAST` adds Optional to the top level and returns `NULL` for such a value.
+
+### Nested containers
+
+* All of the above rules are applied recursively for nested containers.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/containers.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/containers.md
new file mode 100644
index 00000000000..b9146a071d0
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/containers.md
@@ -0,0 +1,24 @@
+# Containers
+
+| Type | Declaration,</br>example | Description |
+| ------------ | ---------------- | ------------- |
+| List | `List<Type>`,</br>`List<Int32>` | A variable-length sequence consisting of same-type elements. |
+| Dictionary | `Dict<KeyType, ValueType>`,</br>`Dict<String,Int32>` | Set of key-value pairs with a fixed type of keys and values. |
+| Set | `Set<KeyType>`,</br>`Set<String>` | A set of elements with a fixed type is a special case of a dictionary with the `Void` value type. |
+| Tuple | `Tuple<Type1, ..., TypeN>`,</br>`Tuple<Int32,Double>` | Set of unnamed fixed-length elements with types specified for all elements. |
+| Structure | `Struct<Name1:Type1, ..., NameN:TypeN>`,</br> `Struct<Name:String,Age:Int32>` | A set of named fields with specified value types, fixed at query start (must be data-independent). |
+| Stream | `Stream<Type>`,</br> `Stream<Int32>` | Single-pass iterator by same-type values, not serializable |
+| Variant on tuple | `Variant<Type1, Type2>`,</br> `Variant<Int32,String>` | A tuple known to have exactly one element filled |
+| Variant on structure | `Variant<Name1:Type1, Name2:Type2>`,</br>`Variant<value:Int32,error:String>` | A structure known to have exactly one element filled |
+| Enumeration | `Enum<Name1, Name2>`,</br>`Enum<value,error>` | A container with exactly one enumeration element selected and defined only by its name. |
+
+If needed, you can nest containers into each other in arbitrary combinations, for example: `List<TupleInt32,Int32>`.
+
+[In certain contexts, optional values](../optional.md) can also be considered a container type (`Optional<Type>`) that behaves as a list of length 0 or 1.
+
+To create literals of list containers, dictionary containers, set containers, tuple containers, or structure containers, you can use the [operator notation](../../builtins/basic.md#containerliteral).
+To create a variant literal over a tuple or structure, use the function [Variant](../../builtins/basic.md#variant).
+To create an enumeration literal, use the function [Enum](../../builtins/basic.md#enum).
+
+To access container elements, use a [dot or square brackets](../../syntax/expressions.md#items-access), depending on the container type.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_datetime.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_datetime.md
new file mode 100644
index 00000000000..8f96cc3504a
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_datetime.md
@@ -0,0 +1,10 @@
+| Type | Description | Notes |
+| ----- | ----- | ----- |
+| `Date` | Date, precision to the day | Range of values for all time types except `Interval`: From 00:00 01.01.1970 to 00:00 01.01.2106. Internal `Date` representation: Unsigned 16-bit integer |
+| `Datetime` | Date/time, precision to the second | Internal representation: Unsigned 32-bit integer |
+| `Timestamp` | Date/time, precision to the microsecond | Internal representation: Unsigned 64-bit integer |
+| `Interval` | Time interval (signed), precision to microseconds | Value range: From -136 years to +136 years. Internal representation: Signed 64-bit integer. {% if feature_map_tables %}Can't be used in the primary key{% endif %} |
+| `TzDate` | Date with time zone label, precision to the day | Not supported in table columns |
+| `TzDateTime` | Date/time with time zone label, precision to the second | Not supported in table columns |
+| `TzTimestamp` | Date/time with time zone label, precision to the microsecond | Not supported in table columns |
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_number.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_number.md
new file mode 100644
index 00000000000..75a55b38e16
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_number.md
@@ -0,0 +1,19 @@
+| Type | Description | Notes |
+| ----- | ----- | ----- |
+| `Bool ` | Boolean value. |
+| `Int8` | A signed integer.<br/>Acceptable values: from -2<sup>7</sup> to 2<sup>7</sup>–1. | Not supported for table columns |
+| `Int16` | A signed integer.<br/>Acceptable values: from –2<sup>15</sup> to 2<sup>15</sup>–1. | Not supported for table columns |
+| `Int32` | A signed integer.<br/>Acceptable values: from –2<sup>31</sup> to 2<sup>31</sup>–1. |
+| `Int64` | A signed integer.<br/>Acceptable values: from –2<sup>63</sup> to 2<sup>63</sup>–1. |
+| `Uint8` | An unsigned integer.<br/>Acceptable values: from 0 to 2<sup>8</sup>–1. |
+| `Uint16` | An unsigned integer.<br/>Acceptable values: from 0 to 2<sup>16</sup>–1. | Not supported for table columns |
+| `Uint32` | An unsigned integer.<br/>Acceptable values: from 0 to 2<sup>32</sup>–1. |
+| `Uint64` | An unsigned integer.<br/>Acceptable values: from 0 to 2<sup>64</sup>–1. |
+| `Float` | A real number with variable precision, 4 bytes in size. | {% if feature_map_tables %}Can't be used in the primary key{% endif %} |
+| `Double` | A real number with variable precision, 8 bytes in size. | {% if feature_map_tables %}Can't be used in the primary key{% endif %} |
+| `Decimal` | A real number with the specified precision, up to 35 decimal digits | {% if feature_map_tables %}When used in table columns, precision is fixed: Decimal (22,9).</br>Can't be used in the primary key{% endif %} |
+
+{% if feature_map_tables %}
+`DyNumber` | A binary representation of a real number with an accuracy of up to 38 digits.<br/>Acceptable values: positive numbers from 1×10<sup>-130</sup> up to 1×10<sup>126</sup>–1, negative numbers from -1×10<sup>126</sup>–1 to -1×10<sup>-130</sup>, and 0.<br/>Compatible with the `Number` type in AWS DynamoDB. It's not recommended for {{ backend_name_lower }}-native applications. |
+{% endif %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md
new file mode 100644
index 00000000000..95d59aafc61
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md
@@ -0,0 +1,27 @@
+| Type | Description | Notes |
+| ----- | ----- | ----- |
+| `String` | A string that can contain any binary data |
+| `Utf8` | Text encoded in [UTF-8](https://en.wikipedia.org/wiki/UTF-8) |
+| `Json` | [JSON](https://en.wikipedia.org/wiki/JSON) represented as text | Doesn't support matching{% if feature_map_tables %}, can't be used in the primary key{% endif %} |
+| `JsonDocument` | [JSON](https://en.wikipedia.org/wiki/JSON) in an indexed binary representation | Doesn't support matching{% if feature_map_tables %}, can't be used in the primary key{% endif %} |
+| `Yson` | [YSON](https://yt.yandex-team.ru/docs/description/common/yson.html) in a textual or binary representation. | Doesn't support matching{% if feature_map_tables %}, can't be used in the primary key{% endif %} |
+| `Uuid` | Universally unique identifier [UUID](https://tools.ietf.org/html/rfc4122) | Not supported for table columns |
+
+{% note info "Cell size restrictions" %}
+
+The maximum value size for a {% if feature_map_tables %}non-key {% endif %} column cell with any string data type is 8 MB.
+
+{% endnote %}
+
+Unlike the `JSON` data type that stores the original text representation passed by the user, `JsonDocument` uses an indexed binary representation. An important difference from the point of view of semantics is that `JsonDocument` doesn't preserve formatting, the order of keys in objects, or their duplicates.
+
+Thanks to the indexed view, `JsonDocument` lets you bypass the document model using `JsonPath` without the need to parse the full content. This helps efficiently perform operations from the [JSON API](../../builtins/json.md), reducing delays and cost of user queries. Execution of `JsonDocument` queries can be up to several times more efficient depending on the type of load.
+
+Due to the added redundancy, `JsonDocument` is less effective in storage. The additional storage overhead depends on the specific content, but is 20-30% of the original volume on average. Saving data in `JsonDocument` format requires additional conversion from the textual representation, which makes writing it less efficient. However, for most read-intensive scenarios that involve processing data from JSON, this data type is preferred and recommended.
+
+{% note warning %}
+
+To store numbers (JSON Number) in `JsonDocument`, as well as for arithmetic operations on them in the [JSON API](../../builtins/json.md), the [Double](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) type is used. Precision might be lost when non-standard representations of numbers are used in the source JSON document.
+
+{% endnote %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/json.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/json.md
new file mode 100644
index 00000000000..e0be51a4698
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/json.md
@@ -0,0 +1,175 @@
+# Data representation in JSON format
+
+## Bool {#bool}
+
+Boolean value.
+
+* Type in JSON: `bool`.
+* Sample {{ backend_name }} value: `true`.
+* Sample JSON value: `true`.
+
+## Int8, Int16, Int32, Int64 {#int}
+
+Signed integer types.
+
+* Type in JSON: `number`.
+* Sample {{ backend_name }} value: `123456`, `-123456`.
+* Sample JSON value: `123456`, `-123456`.
+
+## Uint8, Uint16, Uint32, Uint64 {#uint}
+
+Unsigned integer types.
+
+* Type in JSON: `number`.
+* Sample {{ backend_name }} value: `123456`.
+* Sample JSON value: `123456`.
+
+## Float {#float}
+
+Real 4-byte number.
+
+* Type in JSON — `number`.
+* Sample {{ backend_name }} value: `0.12345679`.
+* Sample JSON value: `0.12345679`.
+
+## Double {#double}
+
+Real 8-byte number.
+
+* Type in JSON: `number`.
+* Sample {{ backend_name }} value: `0.12345678901234568`.
+* Sample JSON value: `0.12345678901234568`.
+
+## Decimal {#decimal}
+
+Fixed-precision number. Only Decimal(22, 9) is supported.
+
+* Type in JSON: `string`.
+* Sample {{ backend_name }} value: `-320.789`.
+* Sample JSON value: `"-320.789"`.
+
+## String{% if audience != "external" %}, Yson{% endif %} {#string}
+
+Binary strings. Encoding algorithm depending on the byte value:
+
+* [0-31] — `\u00XX` (6 characters denoting the Unicode character code).
+* [32-126] — as is. These are readable single-byte characters that don't need to be escaped.
+* [127-255] — `\u00XX`.
+
+Decoding is a reverse process. Character codes in `\u00XX`, maximum 255.
+
+* Type in JSON: `string`.
+* Sample {{ backend_name }} value: A sequence of 4 bytes:
+ * 5 `0x05`: A control character.
+ * 10 `0x0a`: The `\n` newline character.
+ * 107 `0x6b`: The `k` character.
+ * 255 `0xff`: The `ÿ` character in Unicode.
+* Sample JSON value: `"\u0005\nk\u00FF"`.
+
+## Utf8, Json, Uuid {#utf}
+
+String types in UTF-8. Such strings are represented in JSON as strings with JSON characters escaped: `\\`, `\"`, `\n`, `\r`, `\t`, `\f`.
+
+* Type in JSON: `string`.
+
+* Sample {{ backend_name }} value: C++ code:
+
+ ```c++
+ "Escaped characters: "
+ "\\ \" \f \b \t \r\n"
+ "Non-escaped characters: "
+ "/ ' < > & []() ".
+ ```
+
+* Sample JSON value: `"Escaped characters: \\ \" \f \b \t \r\nNon-escaped characters: / ' < > & []() "`.
+
+## Date {#date}
+
+Date. Uint64, unix time days.
+
+* Type in JSON: `string`.
+* Sample {{ backend_name }} value: `18367`.
+* Sample JSON value: `"2020-04-15"`.
+
+## Datetime {#datetime}
+
+Date and time. Uint64, unix time seconds.
+
+* Type in JSON: `string`.
+* Sample {{ backend_name }} value: `1586966302`.
+* Sample JSON value: `"2020-04-15T15:58:22Z"`.
+
+## Timestamp {#timestamp}
+
+Date and time. Uint64, unix time microseconds.
+
+* Type in JSON: `string`.
+* Sample {{ backend_name }} value: `1586966302504185`.
+* Sample JSON value: `"2020-04-15T15:58:22.504185Z"`.
+
+## Interval {#interval}
+
+Time interval. Int64, precision to the microsecond, the interval values must not exceed 24 hours.
+
+* Type in JSON: `number`.
+* Sample {{ backend_name }} value: `123456`, `-123456`.
+* Sample JSON value: `123456`, `-123456`.
+
+## Optional {#optional}
+
+Means that the value can be `null`. If the value is `null`, then in JSON it's also `null`. If the value is not `null`, then the JSON value is expressed as if the type isn't `Optional`.
+
+* Type in JSON is missing.
+* Sample {{ backend_name }} value: `null`.
+* Sample JSON value: `null`.
+
+## List {#list}
+
+List. An ordered set of values of a given type.
+
+* Type in JSON: `array`.
+* Sample {{ backend_name }} value:
+ * Type: `List<Int32>`.
+ * Value: `1, 10, 100`.
+* Sample JSON value: `[1,10,100]`.
+
+## Stream {#stream}
+
+Stream. Single-pass iterator by same-type values,
+
+* Type in JSON: `array`.
+* Sample {{ backend_name }} value:
+ * Type: `Stream<Int32>`.
+ * Value: `1, 10, 100`.
+* Sample JSON value: `[1,10,100]`.
+
+## Struct {#struct}
+
+Structure. An unordered set of values with the specified names and type.
+
+* Type in JSON: `object`.
+* Sample {{ backend_name }} value:
+ * Type: `Struct<'Id':Uint32,'Name':String,'Value':Int32,'Description':Utf8?>`;
+ * Value: `"Id":1,"Name":"Anna","Value":-100,"Description":null`.
+* Sample JSON value: `{"Id":1,"Name":"Anna","Value":-100,"Description":null}`.
+
+## Tuple {#tuple}
+
+Tuple. An ordered set of values of the set types.
+
+* Type in JSON: `array`.
+* Sample {{ backend_name }} value:
+ * Type: `Tuple<Int32??,Int64???,String??,Utf8???>`;
+ * Value: `10,-1,null,"Some string"`.
+* Sample JSON value: `[10,-1,null,"Some string"]`.
+
+## Dict {#dict}
+
+Dictionary. An unordered set of key-value pairs. The type is set both for the key and the value. It's written in JSON to an array of arrays including two items.
+
+* Type in JSON: `array`.
+* Sample {{ backend_name }} value:
+ * Type: `Dict<Int64,String>`.
+ * Value: `1:"Value1",2:"Value2"`.
+* Sample JSON value: `[[1,"Value1"],[2,"Value2"]]`.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/optional.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/optional.md
new file mode 100644
index 00000000000..71bb96d346e
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/optional.md
@@ -0,0 +1,50 @@
+## Data types accepting NULL
+
+Any typed data in YQL, including table columns, can be either non-nullable (guaranteed value) or nullable (empty value denoted as `NULL`). Data types that can include `NULL` values are called _optional_ or, in SQL terms, _nullable_.
+
+Optional data types in the [text format](../type_string.md) use the question mark at the end (for example, `String?`) or the notation `Optional<...>`.
+The following operations are most often performed on optional data types:
+
+* [IS NULL](../../syntax/expressions.md#is-null): Matching an empty value
+* [COALESCE](../../builtins/basic.md#coalesce): Leaves the filled values unchanged and replaces `NULL` with the default value that follows
+* [UNWRAP](../../builtins/basic.md#optional-ops): Extract the value of the source type from the optional data type, `T?` is converted to `T`
+* [JUST](../../builtins/basic#optional-ops) Change the data type to the optional type of the current one, `T` converts to`T?`
+* [NOTHING](../../builtins/basic.md#optional-ops): Create an empty value with the specified type.
+
+`Optional` (nullable) isn't a property of a data type or column, but a [container](../containers.md) type where containers can be arbitrarily nested into each other. For example, a column with the type `Optional<Optional<Boolean>>` can accept 4 values: `NULL` of the overarching container, `NULL` of the inner container, `TRUE`, and `FALSE`. The above-declared type differs from `List<List<Boolean>>`, because it uses `NULL` as an empty list, and you can't put more than one non-null element in it. You can also use `Optional<Optional<T>>` as a key [lookup](/docs/s_expressions/functions#lookup) in the dictionary (`Dict(k,v)`) with `Optional<T>` values. Using this type of result data, you can distinguish between a `NULL` value in the dictionary and a missing key.
+
+**Example**
+
+```sql
+$dict = {"a":1, "b":null};
+$found = $dict["b"];
+select if($found is not null, unwrap($found), -1);
+```
+
+Result:
+
+```text
+# column0
+0 null
+```
+
+## Logical and arithmetic operations with NULL {#null_expr}
+
+The `NULL` literal has a separate singular `Null` type and can be implicitly converted to any optional type (for example, the nested type `OptionalOptional<T>...>>`). In ANSI SQL, `NULL` means "an unknown value", that's why logical and arithmetic operations involving `NULL` or empty `Optional` have certain specifics.
+
+**Examples**
+
+```
+SELECT
+ True OR NULL, -- Just(True) (works the same way as True OR <unknown value of type Bool>)
+ False AND NULL, -- Just(False)
+ True AND NULL, -- NULL (to be more precise, Nothing<Bool?> – <unknown value of type Bool>)
+ NULL OR NOT NULL, -- NULL (all NULLs are considered "different")
+ 1 + NULL, -- NULL (Nothing<Int32?>) - the result of adding 1 together with
+ -- an unknown Int value)
+ 1 == NULL, -- NULL (the result of comparing 1 with an unknown Int value)
+ (1, NULL) == (1, 2), -- NULL (composite elements are compared by component comparison
+ -- using `AND')
+ (2, NULL) == (1, 3), -- Just(False) (the expression is equivalent to 2 == 1 AND NULL == 3)
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/primitive.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/primitive.md
new file mode 100644
index 00000000000..17791bc2f95
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/primitive.md
@@ -0,0 +1,120 @@
+# Primitive data types
+
+The terms "simple", "primitive", and "elementary" data types are used synonymously.
+
+## Numeric types {#numeric}
+
+{% include [datatypes](datatypes_primitive_number.md) %}
+
+## String types {#string}
+
+{% include [datatypes](datatypes_primitive_string.md) %}
+
+## Date and time {#datetime}
+
+{% include [datatypes](datatypes_primitive_datetime.md) %}
+
+{% include [x](tz_date_types.md) %}
+
+# Casting between data types {#cast}
+
+## Explicit casting {#explicit-cast}
+
+Explicit casting using [CAST](../../syntax/expressions.md#cast):
+
+### Casting to numeric types
+
+| Type | Bool | Int | Uint | Float | Double | Decimal |
+| --- | --- | --- | --- | --- | --- | --- |
+| **Bool** | — | Yes<sup>1</sup> | Yes<sup>1</sup> | Yes<sup>1</sup> | Yes<sup>1</sup> | No | Yes | No |
+| **INT** | Yes<sup>2</sup> | — | Yes<sup>3</sup> | Yes | Yes | Yes |
+| **Uint** | Yes<sup>2</sup> | Yes | — | Yes | Yes | Yes |
+| **Float** | Yes<sup>2</sup> | Yes | Yes | — | Yes | No |
+| **Double** | Yes<sup>2</sup> | Yes | Yes | Yes | — | No |
+| **Decimal** | No | Yes | Yes | Yes | Yes | — |
+| **String** | Yes | Yes | Yes | Yes | Yes | Yes |
+| **Utf8** | Yes | Yes | Yes | Yes | Yes | Yes |
+| **Json** | No | No | No | No | No | No |
+| **Yson** | Yes<sup>4</sup> | Yes<sup>4</sup> | Yes<sup>4</sup> | Yes<sup>4</sup> | Yes<sup>4</sup> | Yes<sup>4</sup> |
+| **Uuid** | No | No | No | No | No | No |
+| **Date** | No | Yes | Yes | Yes | Yes | No | Yes |
+| **Datetime** | No | Yes | Yes | Yes | Yes | No |
+| **Timestamp** | No | Yes | Yes | Yes | Yes | No |
+| **Interval** | No | Yes | Yes | Yes | Yes | No |
+
+<sup>1</sup> `True` is converted to `1` and `False` to `0`.
+<sup>2</sup> Any value other than `0` is converted to `True`, `0` is converted to `False`.
+<sup>3</sup> Possible only in the case of a non-negative value.
+<sup>4</sup> Using the built-in function [Yson::ConvertTo](../../udf/list/yson.md#ysonconvertto).
+
+### Converting to date and time data types
+
+| Type | Date | Datetime | Timestamp | Interval |
+| --- | --- | --- | --- | --- |
+| **Bool** | No | No | No | No |
+| **INT** | Yes | Yes | Yes | Yes |
+| **Uint** | Yes | Yes | Yes | Yes |
+| **Float** | No | No | No | No |
+| **Double** | No | No | No | No |
+| **Decimal** | No | No | No | No |
+| **String** | Yes | Yes | Yes | Yes |
+| **Utf8** | Yes | Yes | Yes | Yes |
+| **Json** | No | No | No | No |
+| **Yson** | No | No | No | No |
+| **Uuid** | No | No | No | No |
+| **Date** | — | Yes | Yes | No |
+| **Datetime** | Yes | — | Yes | No |
+| **Timestamp** | Yes | Yes | — | No |
+| **Interval** | No | No | No | — | — |
+
+### Conversion to other data types
+
+| Type | String | Utf8 | Json | Yson | Uuid |
+| --- | --- | --- | --- | --- | --- |
+| **Bool** | Yes | No | No | No | No |
+| **INT** | Yes | No | No | No | No |
+| **Uint** | Yes | No | No | No | No |
+| **Float** | Yes | No | No | No | No |
+| **Double** | Yes | No | No | No | No |
+| **Decimal** | Yes | No | No | No | No |
+| **String** | — | Yes | Yes | Yes | Yes |
+| **Utf8** | Yes | — | No | No | No |
+| **Json** | Yes | Yes | — | No | No |
+| **Yson** | Yes<sup>4</sup> | No | No | No | No |
+| **Uuid** | Yes | Yes | No | No | — |
+| **Date** | Yes | Yes | No | No | No |
+| **Datetime** | Yes | Yes | No | No | No |
+| **Timestamp** | Yes | Yes | No | No | No |
+| **Interval** | Yes | Yes | No | No | No |
+
+<sup>4</sup> Using the built-in function [Yson::ConvertTo](../../udf/list/yson.md#ysonconvertto).
+
+**Examples**
+
+{% include [x](../../_includes/cast_examples.md) %}
+
+## Implicit casting {#implicit-cast}
+
+Implicit type casting that occurs in basic operations ( +-\*/) between different data types. The table cells specify the operation result type, if the operation is possible:
+
+### Numeric types
+
+| Type | Int | Uint | Float | Double |
+| --- | --- | --- | --- | --- |
+| **INT** | — | `INT` | `Float` | `Double` |
+| **Uint** | `INT` | — | `Float` | `Double` |
+| **Float** | `Float` | `Float` | — | `Double` |
+| **Double** | `Double` | `Double` | `Double` | — |
+
+### Date and time types
+
+| Type | Date | Datetime | Timestamp | Interval | TzDate | TzDatetime | TzTimestamp |
+| --- | --- | --- | --- | --- | --- | --- | --- |
+| **Date** | — | — | — | `Date` | — | — | — |
+| **Datetime** | — | — | — | `Datetime` | — | — | — |
+| **Timestamp** | — | — | — | `Timestamp` | — | — | — |
+| **Interval** | `Date` | `Datetime` | `Timestamp` | — | `TzDate` | `TzDatetime` | `TzTimestamp` |
+| **TzDate** | — | — | — | `TzDate` | — | — | — |
+| **TzDatetime** | — | — | — | `TzDatetime` | — | — | — |
+| **TzTimestamp** | — | — | — | `TzTimestamp` | — | — | — |
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/special.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/special.md
new file mode 100644
index 00000000000..2856be9da01
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/special.md
@@ -0,0 +1,14 @@
+# Special data types
+
+| Type | Description |
+| ----- | ----- |
+| `Callable` | A callable value that can be executed by passing arguments in parentheses in YQL SQL syntax{% if feature_mapreduce %} or using the `Apply` function with the [s-expressions](/docs/s_expressions) syntax{% endif %}. |
+| `Resource` | Resource is an opaque pointer to a resource you can pass between the user defined functions (UDF). The type of the returned and accepted resource is declared inside a function using a string label. When passing a resource, YQL checks for label matching to prevent passing of resources between incompatible functions. If the labels mismatch, a type error occurs. |
+| `Tagged` | Tagged is the option to assign an application name to any other type. |
+| `Generic` | The data type used for data types. |
+| `Unit` | Unit is the data type used for non-enumerable entities (data sources and data sinks, atoms, etc.&nbsp;). |
+| `Null` | Void is a singular data type with the only possible null value. It's the type of the `NULL` literal and can be converted to any `Optional` type. |
+| `Void` | Void is a singular data type with the only possible ` "null" value`. |
+| `EmptyList` | A singular data type with the only possible [] value. It's the type of the `[]` literal and can be converted to any `List` type. |
+| `EmptyDict` | A singular data type with the only possible {} value. It's a type of the `{}` literal and can be converted to any `Dict` or `Set` type. |
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/type_string.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/type_string.md
new file mode 100644
index 00000000000..2660b7e213c
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/type_string.md
@@ -0,0 +1,74 @@
+# Text representation of data types
+
+## Introduction {#intro}
+
+Since YQL is a strongly typed language, the data type is important for many of its aspects. To make data type management easy, YQL has a data type definition convention in text format. It's mentioned in many places in the documentation. There's also a library that provides functions for building a data type based on a text description (for example, when manually defining the signature for the called value) or for serializing the data type into a string for debugging purposes.
+
+Functions for data types are [described in the article](../../builtins/types.md). Below is the format of text representation of data types.
+
+## General conventions {#rules}
+
+* [Primitive data types](../primitive.md) are represented in text format simply by referencing their name.
+
+* A complex data type is composed of other data types. If you depict this structure as a tree, it has [primitive data types](../primitive.md) as leaves and [containers](../containers.md) as other nodes. [You may treat special data types](../special.md) as exceptions, because they can function as both.
+
+* The text representation repeats the structure of this tree from the root to the leaves: each node of the tree specifies the name of the current data type, and proceeding to a deeper level is denoted by different types of brackets.
+
+* Feel free to use spaces and line breaks if they improve readability.
+
+* If the ID contains something else except the Latin letters and numbers, put it in single quotes and use C-escaping.
+
+## Containers {#containers}
+
+* Use angle brackets to specify the types of container elements.
+
+ Example: `List<Int32>`.
+
+* If a container can hold multiple heterogeneous elements, they are listed inside angle brackets with a comma.
+
+ Example: `Tuple<Int32, String>`.
+
+* If a container can hold named elements, use comma-separated name-type pairs with a colon in-between instead of comma-separated data types.
+
+ Example: `Struct<a:Int32, b:String>`.
+
+* The underlying `Variant` container type is chosen based on the presence of names in arguments.
+
+ Example: `Variant<Int32, String>` is a variant on tuple, `Variant<a:Int32, b:String>` is a variant on structure.
+
+## Types that allow NULL {#optional}
+
+* They are called `Optional` in YQL terms, or nullable in the classic SQL terms.
+
+* Formally, this type is a container. So, you may declare it as `Optional<...>`, but the shortcut notation of a question mark suffix is usually used instead.
+
+ Example: `String?`.
+
+## Called values {#callable}
+
+* The basic form of the called values looks as follows: `(arg1, arg2, ...) -> result`.
+
+ An example of declaring a function signature that accepts two strings and returns a number: `(String, String) -> Int64`.
+
+* The called values can return the called values: in this case, they make up a chain of the required length.
+
+ Example: `(String, String) -> (String, String) -> Int64`.
+
+* Optional arguments must have the `Optional` type at the top level and be enclosed in square brackets.
+
+ Example: `(String, [String?, Double?]) -> Int64`.
+
+* The arguments of the called values can contain flags.
+
+ Currently, the only possible flag is `AutoMap`. It means that if NULL is passed to this argument, the result must also be set to NULL without running the function.
+
+ Example: `(String{Flags: AutoMap}) -> Int64`.
+
+* Use this particular format if you need `Optional<Callable...>`, because the trailing question mark refers to the result of the called value.
+
+## Resources {#resources}
+
+* Unlike containers, a resource isn't parameterized by the element type (it's a pointer in memory and YQL knows nothing about its contents). Instead, a resource is parameterized by a string label that can safeguard against passing resources between incompatible functions.
+
+ Example: `Resource<Foo>`.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/_includes/tz_date_types.md b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/tz_date_types.md
new file mode 100644
index 00000000000..baa34463aa6
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/_includes/tz_date_types.md
@@ -0,0 +1,19 @@
+### Supporting types with a time zone label
+
+Time zone label for the `TzDate`, `TzDatetime`, `TzTimestamp` types is an attribute that is used:
+
+* When converting ([CAST](../../syntax/expressions.md#cast), [DateTime::Parse](../../udf/list/datetime.md#parse), [DateTime::Format](../../udf/list/datetime.md#format)) to a string and from a string.
+* In [DateTime::Split](../../udf/list/datetime.md#split), a timezone component is added to `Resource<TM>`.
+
+The point in time for these types is stored in UTC, and the timezone label doesn't participate in any other calculations in any way. For example:
+
+```yql
+select --these expressions are always true for any timezones: the timezone doesn't affect the point in time.
+ AddTimezone(CurrentUtcDate(), "Europe/Moscow") ==
+ AddTimezone(CurrentUtcDate(), "America/New_York"),
+ AddTimezone(CurrentUtcDatetime(), "Europe/Moscow") ==
+ AddTimezone(CurrentUtcDatetime(), "America/New_York");
+```
+
+Keep in mind that when converting between `TzDate` and `TzDatetime`, or `TzTimestamp` the date's midnight doesn't follow the local time zone, but midnight in UTC for the date in UTC.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/cast.md b/ydb/docs/en/core/yql/reference/yql-core/types/cast.md
new file mode 100644
index 00000000000..cacca351321
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/cast.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/cast.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/containers.md b/ydb/docs/en/core/yql/reference/yql-core/types/containers.md
new file mode 100644
index 00000000000..6d4196bdb95
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/containers.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/containers.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/index.md b/ydb/docs/en/core/yql/reference/yql-core/types/index.md
new file mode 100644
index 00000000000..f1c2fbab3b2
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/index.md
@@ -0,0 +1,12 @@
+# YQL data types
+
+This section contains articles on YQL data types:
+
+- [Simple/Primitive types](primitive.md)
+- [Optional types](optional.md)
+- [Containers](containers.md)
+- [Special types](special.md)
+- [Type casting](cast.md)
+- [Text representation of data types](type_string.md)
+- [Data representation in JSON format](json.md)
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/json.md b/ydb/docs/en/core/yql/reference/yql-core/types/json.md
new file mode 100644
index 00000000000..2a96f5886ec
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/json.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/json.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/optional.md b/ydb/docs/en/core/yql/reference/yql-core/types/optional.md
new file mode 100644
index 00000000000..a2722f9f6b4
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/optional.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/optional.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/primitive.md b/ydb/docs/en/core/yql/reference/yql-core/types/primitive.md
new file mode 100644
index 00000000000..121b1095423
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/primitive.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/primitive.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/special.md b/ydb/docs/en/core/yql/reference/yql-core/types/special.md
new file mode 100644
index 00000000000..bed7bcb5571
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/special.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/special.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/toc_i.yaml b/ydb/docs/en/core/yql/reference/yql-core/types/toc_i.yaml
new file mode 100644
index 00000000000..060dd02891f
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/toc_i.yaml
@@ -0,0 +1,17 @@
+items:
+- name: Overview
+ href: index.md
+- name: Simple
+ href: primitive.md
+- name: Optional
+ href: optional.md
+- name: Containers
+ href: containers.md
+- name: Special
+ href: special.md
+- name: Type casting
+ href: cast.md
+- name: Text representation of data types
+ href: type_string.md
+- name: JSON
+ href: json.md \ No newline at end of file
diff --git a/ydb/docs/en/core/yql/reference/yql-core/types/type_string.md b/ydb/docs/en/core/yql/reference/yql-core/types/type_string.md
new file mode 100644
index 00000000000..acbdaff6a48
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/types/type_string.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/type_string.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/histogram.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/histogram.md
new file mode 100644
index 00000000000..7996a3b2eaf
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/histogram.md
@@ -0,0 +1,19 @@
+# Histogram
+
+Set of auxiliary functions for the [HISTOGRAM aggregate function](../../../builtins/aggregation.md). In the signature description below, HistogramStruct refers to the result of the aggregate function `HISTOGRAM`, `LinearHistogram` or `LogarithmicHistogram` being a structure of a certain type.
+
+**List of functions**
+
+* ```Histogram::Print(HistogramStruct{Flags:AutoMap}, Byte?) -> String```
+* ```Histogram::Normalize(HistogramStruct{Flags:AutoMap}, [Double?]) -> HistogramStruct```: The second argument specifies the desired area of the histogram, 100 by default.
+* ```Histogram::ToCumulativeDistributionFunction(HistogramStruct{Flags:AutoMap}) -> HistogramStruct```
+* ```Histogram::GetSumAboveBound(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+* ```Histogram::GetSumBelowBound(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+* ```Histogram::GetSumInRange(HistogramStruct{Flags:AutoMap}, Double, Double) -> Double```
+* ```Histogram::CalcUpperBound(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+* ```Histogram::CalcLowerBound(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+* ```Histogram::CalcUpperBoundSafe(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+* ```Histogram::CalcLowerBoundSafe(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+
+`Histogram::Print` has an optional numeric argument that sets the maximum length of the histogram columns (the length is in characters, since the histogram is rendered in ASCII art). Default: 25. This function is primarily intended for viewing histograms in the console{% if feature_webui %}. [The web interface](../../../interfaces/web.md) automatically makes an interactive visualization from them{% endif %}.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/index/intro.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/index/intro.md
new file mode 100644
index 00000000000..6ca0040a522
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/index/intro.md
@@ -0,0 +1,4 @@
+# Functions of built-in C++ libraries
+
+Many application functions that on the one hand are too specific to become part of the YQL core, and on the other hand might be useful to a wide range of users, are available through built-in C++ libraries.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/index/list.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/index/list.md
new file mode 100644
index 00000000000..cf1261d8fed
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/index/list.md
@@ -0,0 +1,13 @@
+* [Hyperscan](../../hyperscan.md)
+* [Pcre](../../pcre.md)
+* [Pire](../../pire.md)
+* [Re2](../../re2.md)
+* [String](../../string.md)
+* [Unicode](../../unicode.md)
+* [DateTime](../../datetime.md)
+* [Url](../../url.md)
+* [Ip](../../ip.md)
+* [Yson](../../yson.md)
+* [Digest](../../digest.md)
+* [Math](../../math.md)
+* [Histogram](../../histogram.md) \ No newline at end of file
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/string.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/string.md
new file mode 100644
index 00000000000..8298c9d2f99
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/string.md
@@ -0,0 +1,146 @@
+# String
+
+Functions for ASCII strings:
+
+**List of functions**
+
+* ```String::Base64Encode(String{Flags:AutoMap}) -> String```
+
+* ```String::Base64Decode(String) -> String?```
+
+* ```String::Base64StrictDecode(String) -> String?```
+
+* ```String::EscapeC(String{Flags:AutoMap}) -> String```
+
+* ```String::UnescapeC(String{Flags:AutoMap}) -> String```
+
+* ```String::HexEncode(String{Flags:AutoMap}) -> String```
+
+* ```String::HexDecode(String) -> String?```
+
+* ```String::EncodeHtml(String{Flags:AutoMap}) -> String```
+
+* ```String::DecodeHtml(String{Flags:AutoMap}) -> String```
+
+* ```String::CgiEscape(String{Flags:AutoMap}) -> String```
+
+* ```String::CgiUnescape(String{Flags:AutoMap}) -> String```
+
+* ```String::Strip(String{Flags:AutoMap}) -> String```
+
+* ```String::Collapse(String{Flags:AutoMap}) -> String```
+
+* ```String::CollapseText(String{Flags:AutoMap}, Uint64) -> String```
+
+* ```String::Contains(String?, String) -> Bool```
+
+* ```String::Find(String{Flags:AutoMap}, String, [Uint64?]) -> Int64```: Returns the first position found or -1. The optional argument is the offset from the beginning of the string.
+
+* ```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::HasPrefix(String?, String) -> Bool```
+
+* ```String::HasPrefixIgnoreCase(String?, String) -> Bool```
+
+* ```String::StartsWith(String?, String) -> Bool```
+
+* ```String::StartsWithIgnoreCase(String?, String) -> Bool```
+
+* ```String::HasSuffix(String?, String) -> Bool```
+
+* ```String::HasSuffixIgnoreCase(String?, String) -> Bool```
+
+* ```String::EndsWith(String?, String) -> Bool```
+
+* ```String::EndsWithIgnoreCase(String?, String) -> Bool```
+
+* ```String::Substring(String{Flags:AutoMap}, [Uint64?, Uint64?]) -> String```
+
+* ```String::AsciiToLower(String{Flags:AutoMap}) -> String```: Changes only Latin characters. For working with other alphabets, see Unicode::ToLower
+
+* ```String::AsciiToUpper(String{Flags:AutoMap}) -> String```: Changes only Latin characters. For working with other alphabets, see Unicode::ToUpper
+
+* ```String::AsciiToTitle(String{Flags:AutoMap}) -> String```: Changes only Latin characters. For working with other alphabets, see Unicode::ToTitle
+
+* ```String::SplitToList( String?, String, [ DelimeterString:Bool?, SkipEmpty:Bool?, Limit:Uint64? ]) -> List<String>```
+ The first argument is the source string
+ The second argument is a delimiter
+ The third argument includes the following parameters:
+ - DelimeterString:Bool? — treating a delimiter as a string (true, by default) or a set of characters "any of" (false)
+ - SkipEmpty:Bool? — whether to skip empty strings in the result, is false by default
+ - Limit:Uint64? — Limits the number of fetched components (unlimited by default); if the limit is exceeded, the raw suffix of the source string is returned in the last item
+
+* ```String::JoinFromList(List<String>{Flags:AutoMap}, String) -> String```
+
+* ```String::ToByteList(List<String>{Flags:AutoMap}) -> List<Byte>```
+
+* ```String::FromByteList(List<Uint8>) -> String```
+
+* ```String::ReplaceAll(String{Flags:AutoMap}, String, String) -> String```: Arguments: input, find, replacement
+
+* ```String::ReplaceFirst(String{Flags:AutoMap}, String, String) -> String```: Arguments: input, find, replacement, the second argument is 1 character
+
+* ```String::ReplaceLast(String{Flags:AutoMap}, String, String) -> String```: Arguments: input, find, replacement, the second argument is 1 character
+
+* ```String::RemoveAll(String{Flags:AutoMap}, String) -> String```: The second argument is interpreted as an unordered set of characters to delete
+
+* ```String::RemoveFirst(String{Flags:AutoMap}, String) -> String```: The character to delete in the second argument
+
+* ```String::RemoveLast(String{Flags:AutoMap}, String) -> String ```: The character to delete in the second argument
+
+* ```String::IsAscii(String{Flags:AutoMap}) -> Bool```
+
+* ```String::IsAsciiSpace(String{Flags:AutoMap}) -> Bool```
+
+* ```String::IsAsciiUpper(String{Flags:AutoMap}) -> Bool```
+
+* ```String::IsAsciiLower(String{Flags:AutoMap}) -> Bool```
+
+* ```String::IsAsciiAlpha(String{Flags:AutoMap}) -> Bool```
+
+* ```String::IsAsciiAlnum(String{Flags:AutoMap}) -> Bool```
+
+* ```String::IsAsciiHex(String{Flags:AutoMap}) -> Bool```
+
+* ```String::LevensteinDistance(String{Flags:AutoMap}, String{Flags:AutoMap}) -> Uint64```
+
+* ```String::LeftPad(String{Flags:AutoMap}, Uint64, [String?]) -> String```
+
+* ```String::RightPad(String{Flags:AutoMap}, Uint64) -> String```
+
+* ```String::Hex(Uint64{Flags:AutoMap}) -> String```
+
+* ```String::SHex(Int64{Flags:AutoMap}) -> String```
+
+* ```String::Bin(Uint64{Flags:AutoMap}) -> String```
+
+* ```String::SBin(Int64{Flags:AutoMap}) -> String```
+
+* ```String::HexText(String{Flags:AutoMap}) -> String```
+
+* ```String::BinText(String{Flags:AutoMap}) -> String```
+
+* ```String::HumanReadableDuration(Uint64{Flags:AutoMap}) -> String```
+
+* ```String::HumanReadableQuantity(Uint64{Flags:AutoMap}) -> String```
+
+* ```String::HumanReadableBytes(Uint64{Flags:AutoMap}) -> String```
+
+* ```String::Prec(Double{Flags:AutoMap}, Uint64) -> String* ```
+
+* ```String::Reverse(String?) -> String?```
+
+{% note alert %}
+
+The functions from the String library don't support Cyrillic and can only work with ASCII characters. To work with UTF-8 encoded strings, use functions from [Unicode](../unicode.md).
+
+{% endnote %}
+
+**Examples**
+
+```sql
+SELECT String::Base64Encode("YQL"); -- "WVFM"
+SELECT String::Strip("YQL "); -- "YQL"
+SELECT String::SplitToList("1,2,3,4,5,6,7", ",", 3 as Limit); -- ["1", "2", "3", "4,5,6,7"]
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/unicode.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/unicode.md
new file mode 100644
index 00000000000..f9a2f27f4f5
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/unicode.md
@@ -0,0 +1,82 @@
+# Unicode
+
+Functions for Unicode strings.
+
+**List of functions**
+
+* ```Unicode::IsUtf(String) -> Bool```
+ Checks whether a string is a valid UTF-8 sequence. For example, the string ```"\xF0"``` isn't a valid UTF-8 sequence, but the string ```"\xF0\x9F\x90\xB1"``` correctly describes a UTF-8 cat emoji.
+
+* ```Unicode::GetLength(Utf8{Flags:AutoMap}) -> Uint64```
+ Returns the length of a utf-8 string in unicode code points. Surrogate pairs are counted as one character.
+
+* ```Unicode::Find(Utf8{Flags:AutoMap}, Utf8, [Uint64?]) -> Uint64?```
+
+* ```Unicode::RFind(Utf8{Flags:AutoMap}, Utf8, [Uint64?]) -> Uint64?```
+
+* ```Unicode::Substring(Utf8{Flags:AutoMap}, from:Uint64?, len:Uint64?) -> Utf8```
+ Returns a substring starting with ```from``` with the length of ```len``` characters. If the ```len``` argument is omitted, the substring is moved to the end of the source string.
+
+* The ```Unicode::Normalize...``` functions convert the passed UTF-8 string to a [normalization form](https://unicode.org/reports/tr15/#Norm_Forms):
+ * ```Unicode::Normalize(Utf8{Flags:AutoMap}) -> Utf8``` -- NFC
+ * ```Unicode::NormalizeNFD(Utf8{Flags:AutoMap}) -> Utf8```
+ * ```Unicode::NormalizeNFC(Utf8{Flags:AutoMap}) -> Utf8```
+ * ```Unicode::NormalizeNFKD(Utf8{Flags:AutoMap}) -> Utf8```
+ * ```Unicode::NormalizeNFKC(Utf8{Flags:AutoMap}) -> Utf8```
+
+* ```Unicode::Translit(Utf8{Flags:AutoMap}, [String?]) -> Utf8```
+ Transliterates with Latin letters the words from the passed string, consisting entirely of characters of the alphabet of the language passed by the second argument. If no language is specified, the words are transliterated from Russian. Available languages: "kaz", "rus", "tur", and "ukr".
+
+* ```Unicode::LevensteinDistance(Utf8{Flags:AutoMap}, Utf8{Flags:AutoMap}) -> Uint64```
+ Calculates the Levenshtein distance for the passed strings.
+
+* ```Unicode::Fold(Utf8{Flags:AutoMap}, [ Language:String?, DoLowerCase:Bool?, DoRenyxa:Bool?, DoSimpleCyr:Bool?, FillOffset:Bool? ]) -> Utf8```
+ [A case folding](https://www.w3.org/TR/charmod-norm/#definitionCaseFolding) is performed on the passed string. ```Language``` is set according to the same rules as in ```Unicode::Translit()```. ```DoLowerCase``` converts a string to lowercase letters, defaults to ```true```.
+
+* ```Unicode::ReplaceAll(Utf8{Flags:AutoMap}, Utf8, Utf8) -> Utf8```
+ Arguments: ```input```, ```find```, ```replacement```. Replaces all occurrences of the ```find``` string in the ```input``` with ```replacement```.
+
+* ```Unicode::ReplaceFirst(Utf8{Flags:AutoMap}, Utf8, Utf8) -> Utf8```
+ Arguments: ```input```, ```findSymbol```, ```replacementSymbol```. Replaces the first occurrence of the ```findSymbol``` character in the ```input``` with ```replacementSymbol```. The character can't be a surrogate pair.
+
+* ```Unicode::ReplaceLast(Utf8{Flags:AutoMap}, Utf8, Utf8) -> Utf8```
+ Arguments: ```input```, ```findSymbol```, ```replacementSymbol```. Replaces the last occurrence of the ```findSymbol``` character in the ```input``` with ```replacementSymbol```. The character can't be a surrogate pair.
+
+* ```Unicode::RemoveAll(Utf8{Flags:AutoMap}, Utf8) -> Utf8```
+ The second argument is interpreted as an unordered set of characters to be removed. Removes all occurrences.
+
+* ```Unicode::RemoveFirst(Utf8{Flags:AutoMap}, Utf8) -> Utf8```
+ The second argument is interpreted as an unordered set of characters to be removed. Removes the first occurrence.
+
+* ```Unicode::RemoveLast(Utf8{Flags:AutoMap}, Utf8) -> Utf8```
+ The second argument is interpreted as an unordered set of characters to be removed. Removes the last occurrence.
+
+* ```Unicode::ToCodePointList(Utf8{Flags:AutoMap}) -> List<Uint32>```
+
+* ```Unicode::FromCodePointList(List<Uint32>{Flags:AutoMap}) -> Utf8```
+
+* ```Unicode::Reverse(Utf8{Flags:AutoMap}) -> Utf8```
+
+* ```Unicode::ToLower(Utf8{Flags:AutoMap}) -> Utf8```
+
+* ```Unicode::ToUpper(Utf8{Flags:AutoMap}) -> Utf8```
+
+* ```Unicode::ToTitle(Utf8{Flags:AutoMap}) -> Utf8```
+
+* ```Unicode::SplitToList( Utf8?, Utf8, [ DelimeterString:Bool?, SkipEmpty:Bool?, Limit:Uint64? ]) -> List<Utf8>```
+ The first argument is the source string
+ The second argument is a delimiter
+ The third argument includes the following parameters:
+ - DelimeterString:Bool? — treating a delimiter as a string (true, by default) or a set of characters "any of" (false)
+ - SkipEmpty:Bool? - whether to skip empty strings in the result, is false by default
+ - Limit:Uint64? - Limits the number of fetched components (unlimited by default); if the limit is exceeded, the raw suffix of the source string is returned in the last item
+
+* ```Unicode::JoinFromList(List<Utf8>{Flags:AutoMap}, Utf8) -> Utf8```
+
+**Examples**
+
+```sql
+SELECT Unicode::Fold("Eylül", "Turkish" AS Language); -- "eylul"
+SELECT Unicode::GetLength("жніўня"); -- 6
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/url.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/url.md
new file mode 100644
index 00000000000..1c21c062a98
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/url.md
@@ -0,0 +1,211 @@
+# Url
+
+## Normalize {#normalize}
+
+* ```Url::Normalize(String) -> String?```
+
+Normalizes the URL in a robot-friendly way: converts the hostname into lowercase, strips out certain fragments, and so on.
+The normalization result only depends on the URL itself. The normalization **DOES NOT** include operations depending on the external data: transformation based on duplicates, mirrors, etc.
+
+Returned value:
+
+* Normalized URL.
+* `NULL`, if the passed string argument can't be parsed as a URL.
+
+**Examples**
+
+```sql
+SELECT Url::Normalize("hTTp://wWw.yAnDeX.RU/"); -- "http://www.yandex.ru/"
+SELECT Url::Normalize("http://ya.ru#foo"); -- "http://ya.ru/"
+```
+
+## NormalizeWithDefaultHttpScheme {#normalizewithdefaulthttpscheme}
+
+* ```Url::NormalizeWithDefaultHttpScheme(String?) -> String?```
+
+Normalizes similarly to `Url::Normalize`, but inserts the `http://` schema in case there is no schema.
+
+Returned value:
+
+* Normalized URL.
+* Source URL, if the normalization has failed.
+
+**Examples**
+
+```sql
+SELECT Url::NormalizeWithDefaultHttpScheme("wWw.yAnDeX.RU"); -- "http://www.yandex.ru/"
+SELECT Url::NormalizeWithDefaultHttpScheme("http://ya.ru#foo"); -- "http://ya.ru/"
+```
+
+## Encode / Decode {#encode}
+
+Encode a UTF-8 string to the urlencoded format (`Url::Encode`) and back (`Url::Decode`).
+
+**List of functions**
+
+* ```Url::Encode(String?) -> String?```
+* ```Url::Decode(String?) -> String?```
+
+**Examples**
+
+```sql
+SELECT Url::Decode("http://ya.ru/%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0");
+ -- "http://ya.ru/page"
+SELECT Url::Encode("http://ya.ru/page");
+ -- "http://ya.ru/%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0"
+```
+
+## Parse {#parse}
+
+Parses the URL into parts.
+
+* ```Url::Parse(Parse{Flags:AutoMap}) -> Struct< Frag: String?, Host: String?, ParseError: String?, Pass: String?, Path: String?, Port: String?, Query: String?, Scheme: String?, User: String? >```
+
+**Examples**
+
+```sql
+SELECT Url::Parse(
+ "https://en.wikipedia.org/wiki/Isambard_Kingdom_Brunel?s=24&g=h-24#Great_Western_Railway");
+/*
+(
+ "Frag": "Great_Western_Railway",
+ "Host": "en.wikipedia.org",
+ "ParseError": null,
+ "Pass": null,
+ "Path": "/wiki/Isambard_Kingdom_Brunel",
+ "Port": null,
+ "Query": "s=24&g=h-24",
+ "Scheme": "https",
+ "User": null
+)
+*/
+```
+
+## Get... {#get}
+
+Get a component of the URL.
+
+**List of functions**
+
+* ```Url::GetScheme(String{Flags:AutoMap}) -> String```
+
+* ```Url::GetHost(String?) -> String?```
+
+* ```Url::GetHostPort(String?) -> String?```
+
+* ```Url::GetSchemeHost(String?) -> String?```
+
+* ```Url::GetSchemeHostPort(String?) -> String?```
+
+* ```Url::GetPort(String?) -> String?```
+
+* ```Url::GetTail(String?) -> String?``` -- everything following the host: path + query + fragment
+
+* ```Url::GetPath(String?) -> String?```
+
+* ```Url::GetFragment(String?) -> String?```
+
+* ```Url::GetCGIParam(String?, String) -> String?``` -- The second parameter is the name of the intended CGI parameter.
+
+* ```Url::GetDomain(String?, Uint8) -> String?``` -- The second parameter is the required domain level.
+
+* ```Url::GetTLD(String{Flags:AutoMap}) -> String```
+
+* ```Url::IsKnownTLD(String{Flags:AutoMap}) -> Bool``` -- Registered on http://www.iana.org/
+
+* ```Url::IsWellKnownTLD(String{Flags:AutoMap}) -> Bool``` -- Belongs to a small whitelist of com, net, org, ru, and so on.
+
+* ```Url::GetDomainLevel(String{Flags:AutoMap}) -> Uint64```
+
+* ```Url::GetSignificantDomain(String{Flags:AutoMap}, [List<String>?]) -> String```
+ Returns a second-level domain in most cases and a third-level domain for the hostnames like: ***.XXX.YY, where XXX is com, net, org, co, gov, or edu. You can redefine this list using an optional second argument
+
+* ```Url::GetOwner(String{Flags:AutoMap}) -> String```
+ Returns the domain that's most likely owned by an individual or organization. Unlike Url::GetSignificantDomain, it uses a special whitelist. Besides the ***.co.uk domains, it can return a third-level domain used by free hosting sites and blogs (for example: something.livejournal.com)s
+
+**Examples**
+
+```sql
+SELECT Url::GetScheme("https://ya.ru"); -- "https://"
+SELECT Url::GetDomain("http://www.yandex.ru", 2); -- "yandex.ru"
+```
+
+## Cut... {#cut}
+
+* ```Url::CutScheme(String?) -> String?```
+ Returns the passed URL without the schema (http://, https://, etc.).
+
+* ```Url::CutWWW(String?) -> String?```
+ Returns the passed domain without the "www." prefix (if any).
+
+* ```Url::CutWWW2(String?) -> String?```
+ Returns the passed domain without the prefixes like " www.", " www2.", " wwww777." (if any).
+
+* ```Url::CutQueryStringA­ndFragment(String{Flags:AutoMap}) -> String```
+ Returns a copy of the passed URL, stripping out all the CGI parameters and fragments ("?foo=bar" and/or "#baz").
+
+**Examples**
+
+```sql
+SELECT Url::CutScheme("http://www.yandex.ru"); -- "www.yandex.ru"
+SELECT Url::CutWWW("www.yandex.ru"); -- "yandex.ru"
+```
+
+## ...Punycode... {#punycode}
+
+[Punycode](https://en.wikipedia.org/wiki/Punycode) transformations.
+
+**List of functions**
+
+* ```Url::HostNameToPunycode(String{Flag:AutoMap}) -> String?```
+* ```Url::ForceHostNameToPunycode(String{Flag:AutoMap}) -> String```
+* ```Url::PunycodeToHostName(String{Flag:AutoMap}) -> String?```
+* ```Url::ForcePunycodeToHostName(String{Flag:AutoMap}) -> String```
+* ```Url::CanBePunycodeHostName(String{Flag:AutoMap}) -> Bool```
+
+**Examples**
+
+```sql
+SELECT Url::PunycodeToHostName("xn--d1acpjx3f.xn--p1ai"); -- "яндекс.рф"
+```
+
+## ...Query... {#query}
+
+[Query](https://docs.python.org/3/library/urllib.parse.html) transformations.
+
+**List of functions**
+
+```sql
+Url::QueryStringToList(String{Flag:AutoMap}, [
+ KeepBlankValues:Bool?, -- Empty values in percent-encoded queries are interpreted as empty strings, defaults to false.
+ Strict:Bool?, -- If false, parsing errors are ignored and incorrect fields are skipped, defaults to true.
+ MaxFields:Uint32?, -- The maximum number of fields. If exceeded, an exception is thrown. Defaults to Max<Uint32>.
+ Separator:String? -- A key-value pair separator, defaults to '&'.
+]) -> List<Tuple<String, String>>
+Url::QueryStringToDict(String{Flag:AutoMap}, [
+ KeepBlankValues:Bool?, -- Empty values in percent-encoded queries are interpreted as empty strings, defaults to false.
+ Strict:Bool?, -- If false, parsing errors are ignored and incorrect fields are skipped, defaults to true.
+ MaxFields:Uint32?, -- The maximum number of fields. If exceeded, an exception is thrown. Defaults to Max<Uint32>.
+ Separator:String? -- A key-value pair separator, defaults to '&'.
+]) -> Dict<String, List<String>>
+Url::BuildQueryString(Dict<String, List<String?>>{Flag:AutoMap}, [
+ Separator:String? -- A key-value pair separator, defaults to '&'.
+]) -> String
+Url::BuildQueryString(Dict<String, String?>{Flag:AutoMap}, [
+ Separator:String? -- A key-value pair separator, defaults to '&'.
+]) -> String
+Url::BuildQueryString(List<Tuple<String, String?>>{Flag:AutoMap}, [
+ Separator:String? -- A key-value pair separator, defaults to '&'.
+]) -> String
+```
+
+**Examples**
+
+```sql
+SELECT Url::QueryStringToList("a=1&b=2&a=3"); -- [("a", "1"), ("b", "2"), ("a", "3")]
+SELECT Url::QueryStringToDict("a=1&b=2&a=3"); -- {"b" : ["2"], "a" : ["1", "3"]}
+SELECT Url::BuildQueryString([("a", "1"), ("a", "3"), ("b", "2")]); -- "a=1&a=3&b=2"
+SELECT Url::BuildQueryString({"a" : "1", "b" : "2"}); -- "b=2&a=1"
+SELECT Url::BuildQueryString({"a" : ["1", "3"], "b" : ["2", "4"]}); -- "b=2&b=4&a=1&a=3"
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/intro_footer.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/intro_footer.md
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/intro_footer.md
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/intro_header.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/intro_header.md
new file mode 100644
index 00000000000..f2b39dec3b6
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/intro_header.md
@@ -0,0 +1,2 @@
+YSON is a JSON-like data format developed at Yandex.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/ypath_overlay.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/ypath_overlay.md
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/_includes/yson/ypath_overlay.md
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/datetime.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/datetime.md
new file mode 100644
index 00000000000..17fa7ce0255
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/datetime.md
@@ -0,0 +1,473 @@
+# DateTime
+
+In the DateTime module, the main internal representation format is `Resource<TM>`, which stores the following date components:
+
+* Year (12 bits).
+* Month (4 bits).
+* Day (5 bits).
+* Hour (5 bits).
+* Minute (6 bits).
+* Second (6 bits).
+* Microsecond (20 bits).
+* TimezoneId (16 bits).
+* DayOfYear (9 bits): Day since the beginning of the year.
+* WeekOfYear (6 bits): Week since the beginning of the year, January 1 is always in week 1.
+* WeekOfYearIso8601 (6 bits): Week of the year according to ISO 8601 (the first week is the one that includes January 4).
+* DayOfWeek (3 bits): Day of the week.
+
+If the timezone is not GMT, the components store the local time for the relevant timezone.
+
+## Split {#split}
+
+Conversion from a primitive type to an internal representation. It's always successful on a non-empty input.
+
+**List of functions**
+
+* ```DateTime::Split(Date{Flags:AutoMap}) -> Resource<TM>```
+* ```DateTime::Split(Datetime{Flags:AutoMap}) -> Resource<TM>```
+* ```DateTime::Split(Timestamp{Flags:AutoMap}) -> Resource<TM>```
+* ```DateTime::Split(TzDate{Flags:AutoMap}) -> Resource<TM>```
+* ```DateTime::Split(TzDatetime{Flags:AutoMap}) -> Resource<TM>```
+* ```DateTime::Split(TzTimestamp{Flags:AutoMap}) -> Resource<TM>```
+
+Functions that accept `Resource<TM>` as input, can be called directly from the primitive date/time type. An implicit conversion will be made in this case by calling a relevant `Split` function.
+
+## Make... {#make}
+
+Making a primitive type from an internal representation. It's always successful on a non-empty input.
+
+**List of functions**
+
+* ```DateTime::MakeDate(Resource<TM>{Flags:AutoMap}) -> Date```
+* ```DateTime::MakeDatetime(Resource<TM>{Flags:AutoMap}) -> Datetime```
+* ```DateTime::MakeTimestamp(Resource<TM>{Flags:AutoMap}) -> Timestamp```
+* ```DateTime::MakeTzDate(Resource<TM>{Flags:AutoMap}) -> TzDate```
+* ```DateTime::MakeTzDatetime(Resource<TM>{Flags:AutoMap}) -> TzDatetime```
+* ```DateTime::MakeTzTimestamp(Resource<TM>{Flags:AutoMap}) -> TzTimestamp```
+
+**Examples**
+
+```yql
+SELECT
+ DateTime::MakeTimestamp(DateTime::Split(Datetime("2019-01-01T15:30:00Z"))),
+ -- 2019-01-01T15:30:00.000000Z
+ DateTime::MakeDate(Datetime("2019-01-01T15:30:00Z")),
+ -- 2019-01-01
+ DateTime::MakeTimestamp(DateTime::Split(TzDatetime("2019-01-01T00:00:00,Europe/Moscow"))),
+ -- 2018-12-31T21:00:00Z (conversion to UTC)
+ DateTime::MakeDate(TzDatetime("2019-01-01T12:00:00,GMT"))
+ -- 2019-01-01 (Datetime -> Date with implicit Split)>
+```
+
+## Get... {#get}
+
+Extracting a component from an internal representation.
+
+**List of functions**
+
+* ```DateTime::GetYear(Resource<TM>{Flags:AutoMap}) -> Uint16```
+* ```DateTime::GetDayOfYear(Resource<TM>{Flags:AutoMap}) -> Uint16```
+* ```DateTime::GetMonth(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetMonthName(Resource<TM>{Flags:AutoMap}) -> String```
+* ```DateTime::GetWeekOfYear(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetWeekOfYearIso8601(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetDayOfMonth(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetDayOfWeek(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetDayOfWeekName(Resource<TM>{Flags:AutoMap}) -> String```
+* ```DateTime::GetHour(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetMinute(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetSecond(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetMillisecondOfSecond(Resource<TM>{Flags:AutoMap}) -> Uint32```
+* ```DateTime::GetMicrosecondOfSecond(Resource<TM>{Flags:AutoMap}) -> Uint32```
+* ```DateTime::GetTimezoneId(Resource<TM>{Flags:AutoMap}) -> Uint16```
+* ```DateTime::GetTimezoneName(Resource<TM>{Flags:AutoMap}) -> String```
+
+**Examples**
+
+```yql
+$tm = DateTime::Split(TzDatetime("2019-01-09T00:00:00,Europe/Moscow"));
+
+SELECT
+ DateTime::GetDayOfMonth($tm) as Day, -- 9
+ DateTime::GetMonthName($tm) as Month, -- "January"
+ DateTime::GetYear($tm) as Year, -- 2019
+ DateTime::GetTimezoneName($tm) as TzName, -- "Europe/Moscow"
+ DateTime::GetDayOfWeekName($tm) as WeekDay; -- "Wednesday"
+```
+
+## Update {#update}
+
+Updating one or more components in the internal representation. Returns either an updated copy or NULL, if an update produces an invalid date or other inconsistencies.
+
+**List of functions**
+
+* ```DateTime::Update( Resource<TM>{Flags:AutoMap}, [ Year:Uint16?, Month:Uint8?, Day:Uint8?, Hour:Uint8?, Minute:Uint8?, Second:Uint8?, Microsecond:Uint32?, Timezone:String? ]) -> Resource<TM>?```
+
+**Examples**
+
+```yql
+$tm = DateTime::Split(Timestamp("2019-01-01T01:02:03.456789Z"));
+
+SELECT
+ DateTime::MakeDate(DateTime::Update($tm, 2012)), -- 2012-01-01
+ DateTime::MakeDate(DateTime::Update($tm, 2000, 6, 6)), -- 2000-06-06
+ DateTime::MakeDate(DateTime::Update($tm, NULL, 2, 30)), -- NULL (February 30)
+ DateTime::MakeDatetime(DateTime::Update($tm, NULL, NULL, 31)), -- 2019-01-31T01:02:03Z
+ DateTime::MakeDatetime(DateTime::Update($tm, 15 as Hour, 30 as Minute)), -- 2019-01-01T15:30:03Z
+ DateTime::MakeTimestamp(DateTime::Update($tm, 999999 as Microsecond)), -- 2019-01-01T01:02:03.999999Z
+ DateTime::MakeTimestamp(DateTime::Update($tm, "Europe/Moscow" as Timezone)), -- 2018-12-31T22:02:03.456789Z (conversion to UTC)
+ DateTime::MakeTzTimestamp(DateTime::Update($tm, "Europe/Moscow" as Timezone)); -- 2019-01-01T01:02:03.456789,Europe/Moscow
+```
+
+## From... {#from}
+
+Getting a Timestamp from the number of seconds/milliseconds/microseconds since the UTC epoch. When the Timestamp limits are exceeded, NULL is returned.
+
+**List of functions**
+
+* ```DateTime::FromSeconds(Uint32{Flags:AutoMap}) -> Timestamp```
+* ```DateTime::FromMilliseconds(Uint64{Flags:AutoMap}) -> Timestamp```
+* ```DateTime::FromMicroseconds(Uint64{Flags:AutoMap}) -> Timestamp```
+
+## To... {#to}
+
+Getting a number of seconds/milliseconds/microseconds since the UTC Epoch from a primitive type.
+
+**List of functions**
+
+* ```DateTime::ToSeconds(Date/DateTime/Timestamp/TzDate/TzDatetime/TzTimestamp{Flags:AutoMap}) -> Uint32```
+* ```DateTime::ToMilliseconds(Date/DateTime/Timestamp/TzDate/TzDatetime/TzTimestamp{Flags:AutoMap}) -> Uint64```
+* ```DateTime::ToMicroseconds(Date/DateTime/Timestamp/TzDate/TzDatetime/TzTimestamp{Flags:AutoMap}) -> Uint64```
+
+**Examples**
+
+```yql
+SELECT
+ DateTime::FromSeconds(1546304523), -- 2019-01-01T01:02:03.000000Z
+ DateTime::ToMicroseconds(Timestamp("2019-01-01T01:02:03.456789Z")); -- 1546304523456789
+```
+
+## Interval... {#interval}
+
+Conversions between ```Interval``` and various time units.
+
+**List of functions**
+
+* ```DateTime::ToDays(Interval{Flags:AutoMap}) -> Int16```
+* ```DateTime::ToHours(Interval{Flags:AutoMap}) -> Int32```
+* ```DateTime::ToMinutes(Interval{Flags:AutoMap}) -> Int32```
+* ```DateTime::ToSeconds(Interval{Flags:AutoMap}) -> Int32```
+* ```DateTime::ToMilliseconds(Interval{Flags:AutoMap}) -> Int64```
+* ```DateTime::ToMicroseconds(Interval{Flags:AutoMap}) -> Int64```
+* ```DateTime::IntervalFromDays(Int16{Flags:AutoMap}) -> Interval```
+* ```DateTime::IntervalFromHours(Int32{Flags:AutoMap}) -> Interval```
+* ```DateTime::IntervalFromMinutes(Int32{Flags:AutoMap}) -> Interval```
+* ```DateTime::IntervalFromSeconds(Int32{Flags:AutoMap}) -> Interval```
+* ```DateTime::IntervalFromMilliseconds(Int64{Flags:AutoMap}) -> Interval```
+* ```DateTime::IntervalFromMicroseconds(Int64{Flags:AutoMap}) -> Interval```
+
+AddTimezone doesn't affect the output of ToSeconds() in any way, because ToSeconds() always returns GMT time.
+
+You can also create an Interval from a string literal in the format [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601%23Durations).
+
+**Examples**
+
+```yql
+SELECT
+ DateTime::ToDays(Interval("PT3000M")), -- 2
+ DateTime::IntervalFromSeconds(1000000), -- 11 days 13 hours 46 minutes 40 seconds
+ DateTime::ToDays(cast('2018-01-01' as date) - cast('2017-12-31' as date)); --1
+```
+
+## StartOf... / TimeOfDay {#startof}
+
+Get the start of the period including the date/time. If the result is invalid, NULL is returned. If the timezone is different from GMT, then the period start is in the specified time zone.
+
+**List of functions**
+
+* ```DateTime::StartOfYear(Resource<TM>{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::StartOfQuarter(Resource<TM>{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::StartOfMonth(Resource<TM>{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::StartOfWeek(Resource<TM>{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::StartOfDay(Resource<TM>{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::StartOf(Resource<TM>{Flags:AutoMap}, Interval{Flags:AutoMap}) -> Resource<TM>?```
+
+The `StartOf` function is intended for grouping by an arbitrary period within a day. The result differs from the input value only by time components. A period exceeding one day is treated as a day (an equivalent of `StartOfDay`). If a day doesn't include an integer number of periods, the number is rounded to the nearest time from the beginning of the day that is a multiple of the specified period. When the interval is zero, the output is same as the input. A negative interval is treated as a positive one.
+
+The functions treat periods longer than one day in a different manner than the same-name functions in the old library. The time components are always reset to zero (this makes sense, because these functions are mainly used for grouping by the period). You can also specify a time period within a day:
+
+* ```DateTime::TimeOfDay(Resource<TM>{Flags:AutoMap}) -> Interval```
+
+**Examples**
+
+```yql
+SELECT
+ DateTime::MakeDate(DateTime::StartOfYear(Date("2019-06-06"))),
+ -- 2019-01-01 (implicit Split here and below)
+ DateTime::MakeDatetime(DateTime::StartOfQuarter(Datetime("2019-06-06T01:02:03Z"))),
+ -- 2019-04-01T00:00:00Z (time components are reset to zero)
+ DateTime::MakeDate(DateTime::StartOfMonth(Timestamp("2019-06-06T01:02:03.456789Z"))),
+ -- 2019-06-01
+ DateTime::MakeDate(DateTime::StartOfWeek(Date("1970-01-01"))),
+ -- NULL (the beginning of the epoch is Thursday, the beginning of the week is 1969-12-29 that is beyond the limits)
+ DateTime::MakeTimestamp(DateTime::StartOfWeek(Date("2019-01-01"))),
+ -- 2018-12-31T00:00:00Z
+ DateTime::MakeDatetime(DateTime::StartOfDay(Datetime("2019-06-06T01:02:03Z"))),
+ -- 2019-06-06T00:00:00Z
+ DateTime::MakeTzDatetime(DateTime::StartOfDay(TzDatetime("1970-01-01T05:00:00,Europe/Moscow"))),
+ -- NULL (beyond the epoch in GMT)
+ DateTime::MakeTzTimestamp(DateTime::StartOfDay(TzTimestamp("1970-01-02T05:00:00.000000,Europe/Moscow"))),
+ -- 1970-01-02T00:00:00,Europe/Moscow (the beginning of the day in Moscow)
+ DateTime::MakeDatetime(DateTime::StartOf(Datetime("2019-06-06T23:45:00Z"), Interval("PT7H"))),
+ -- 2019-06-06T21:00:00Z
+ DateTime::MakeDatetime(DateTime::StartOf(Datetime("2019-06-06T23:45:00Z"), Interval("PT20M"))),
+ -- 2019-06-06T23:40:00Z
+ DateTime::TimeOfDay(Timestamp("2019-02-14T01:02:03.456789Z"));
+ -- 1 hour 2 minutes 3 seconds 456789 microseconds
+```
+
+## Shift... {#shift}
+
+Add/subtract the specified number of units to/from the component in the internal representation and update the other fields.
+Returns either an updated copy or NULL, if an update produces an invalid date or other inconsistencies.
+
+**List of functions**
+
+* ```DateTime::ShiftYears(Resource<TM>{Flags:AutoMap}, Int32) -> Resource<TM>?```
+* ```DateTime::ShiftQuarters(Resource<TM>{Flags:AutoMap}, Int32) -> Resource<TM>?```
+* ```DateTime::ShiftMonths(Resource<TM>{Flags:AutoMap}, Int32) -> Resource<TM>?```
+
+If the resulting number of the day in the month exceeds the maximum allowed, then the `Day` field will accept the last day of the month without changing the time (see examples).
+
+**Examples**
+
+```yql
+$tm1 = DateTime::Split(DateTime("2019-01-31T01:01:01Z"));
+$tm2 = DateTime::Split(TzDatetime("2049-05-20T12:34:50,Europe/Moscow"));
+
+SELECT
+ DateTime::MakeDate(DateTime::ShiftYears($tm1, 10)), -- 2029-01-31T01:01:01
+ DateTime::MakeDate(DateTime::ShiftYears($tm2, -10000)), -- NULL (beyond the limits)
+ DateTime::MakeDate(DateTime::ShiftQuarters($tm2, 0)), -- 2049-05-20T12:34:50,Europe/Moscow
+ DateTime::MakeDate(DateTime::ShiftQuarters($tm1, -3)), -- 2018-04-30T01:01:01
+ DateTime::MakeDate(DateTime::ShiftMonths($tm1, 1)), -- 2019-02-28T01:01:01
+ DateTime::MakeDate(DateTime::ShiftMonths($tm1, -35)), -- 2016-02-29T01:01:01
+```
+
+## Format {#format}
+
+Get a string representation of a time using an arbitrary formatting string.
+
+**List of functions**
+
+* ```DateTime::Format(String) -> (Resource<TM>{Flags:AutoMap}) -> String```
+
+A subset of specifiers similar to strptime is implemented for the formatting string.
+
+* `%%`: % character.
+* `%Y`: 4-digit year.
+* `%m`: 2-digit month.
+* `%d`: 2-digit day.
+* `%H`: 2-digit hour.
+* `%M`: 2-digit minutes.
+* `%S`: 2-digit seconds -- or xx.xxxxxx in the case of non-empty microseconds.
+* `%z`: +hhmm or -hhmm.
+* `%Z`: IANA name of the timezone.
+* `%b`: A short three-letter English name of the month (Jan).
+* `%B`: A full English name of the month (January).
+
+All other characters in the format string are passed on without changes.
+
+**Examples**
+
+```yql
+$format = DateTime::Format("%Y-%m-%d %H:%M:%S %Z");
+
+SELECT
+ $format(DateTime::Split(TzDatetime("2019-01-01T01:02:03,Europe/Moscow")));
+ -- "2019-01-01 01:02:03 Europe/Moscow"
+```
+
+## Parse {#parse}
+
+Parse a string into an internal representation using an arbitrary formatting string. Default values are used for empty fields. If errors are raised, NULL is returned.
+
+**List of functions**
+
+* ```DateTime::Parse(String) -> (String{Flags:AutoMap}) -> Resource<TM>?```
+
+Implemented specifiers:
+
+* `%%`: the % character.
+* `%Y`: 4-digit year (1970).
+* `%m`: 2-digit month (1).
+* `%d`: 2-digit day (1).
+* `%H`: 2-digit hour (0).
+* `%M`: 2-digit minutes (0).
+* `%S`: Seconds (0), can also accept microseconds in the formats from xx. up to xx.xxxxxx
+* `%Z`: The IANA name of the timezone (GMT).
+* `%b`: A short three-letter case-insensitive English name of the month (Jan).
+* `%B`: A full case-insensitive English name of the month (January).
+
+**Examples**
+
+```yql
+$parse1 = DateTime::Parse("%H:%M:%S");
+$parse2 = DateTime::Parse("%S");
+$parse3 = DateTime::Parse("%m/%d/%Y");
+$parse4 = DateTime::Parse("%Z");
+
+SELECT
+ DateTime::MakeDatetime($parse1("01:02:03")), -- 1970-01-01T01:02:03Z
+ DateTime::MakeTimestamp($parse2("12.3456")), -- 1970-01-01T00:00:12.345600Z
+ DateTime::MakeTimestamp($parse3("02/30/2000")), -- NULL (Feb 30)
+ DateTime::MakeTimestamp($parse4("Canada/Central")); -- 1970-01-01T06:00:00Z (conversion to UTC)
+```
+
+For the common formats, wrappers around the corresponding util methods are supported. You can only get TM with components in the UTC timezone.
+
+**List of functions**
+
+* ```DateTime::ParseRfc822(String{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::ParseIso8601(String{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::ParseHttp(String{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::ParseX509(String{Flags:AutoMap}) -> Resource<TM>?```
+
+**Examples**
+
+```yql
+SELECT
+ DateTime::MakeTimestamp(DateTime::ParseRfc822("Fri, 4 Mar 2005 19:34:45 EST")),
+ -- 2005-03-05T00:34:45Z
+ DateTime::MakeTimestamp(DateTime::ParseIso8601("2009-02-14T02:31:30+0300")),
+ -- 2009-02-13T23:31:30Z
+ DateTime::MakeTimestamp(DateTime::ParseHttp("Sunday, 06-Nov-94 08:49:37 GMT")),
+ -- 1994-11-06T08:49:37Z
+ DateTime::MakeTimestamp(DateTime::ParseX509("20091014165533Z"))
+ -- 2009-10-14T16:55:33Z
+```
+
+## Standard scenarios
+
+**Conversions between strings and seconds**
+
+Converting a string date (in the Moscow timezone) to seconds (in GMT timezone):
+
+```yql
+$datetime_parse = DateTime::Parse("%Y-%m-%d %H:%M:%S");
+$datetime_parse_tz = DateTime::Parse("%Y-%m-%d %H:%M:%S %Z");
+
+SELECT
+ DateTime::ToSeconds(TzDateTime("2019-09-16T00:00:00,Europe/Moscow")) AS md_us1, -- 1568581200
+ DateTime::ToSeconds(DateTime::MakeDatetime($datetime_parse_tz("2019-09-16 00:00:00" || " Europe/Moscow"))), -- 1568581200
+ DateTime::ToSeconds(DateTime::MakeDatetime(DateTime::Update($datetime_parse("2019-09-16 00:00:00"), "Europe/Moscow" as Timezone))), -- 1568581200
+
+ -- INCORRECT (Date imports time as GMT, but AddTimezone has no effect on ToSeconds that always returns GMT time)
+ DateTime::ToSeconds(AddTimezone(Date("2019-09-16"), 'Europe/Moscow')) AS md_us2, -- 1568592000
+```
+
+Converting a string date (in the Moscow timezone) to seconds (in the Moscow timezone). DateTime::ToSeconds() exports only to GMT. That's why we should put timezones aside for a while and use only GMT (as if we assumed for a while that Moscow is in GMT):
+
+```yql
+$date_parse = DateTime::Parse("%Y-%m-%d");
+$datetime_parse = DateTime::Parse("%Y-%m-%d %H:%M:%S");
+$datetime_parse_tz = DateTime::Parse("%Y-%m-%d %H:%M:%S %Z");
+
+SELECT
+ DateTime::ToSeconds(Datetime("2019-09-16T00:00:00Z")) AS md_ms1, -- 1568592000
+ DateTime::ToSeconds(Date("2019-09-16")) AS md_ms2, -- 1568592000
+ DateTime::ToSeconds(DateTime::MakeDatetime($date_parse("2019-09-16"))) AS md_ms3, -- 1568592000
+ DateTime::ToSeconds(DateTime::MakeDatetime($datetime_parse("2019-09-16 00:00:00"))) AS md_ms4, -- 1568592000
+ DateTime::ToSeconds(DateTime::MakeDatetime($datetime_parse_tz("2019-09-16 00:00:00 GMT"))) AS md_ms5, -- 1568592000
+
+ -- INCORRECT (imports the time in the Moscow timezone, but RemoveTimezone doesn't affect ToSeconds in any way)
+ DateTime::ToSeconds(RemoveTimezone(TzDatetime("2019-09-16T00:00:00,Europe/Moscow"))) AS md_ms6, -- 1568581200
+ DateTime::ToSeconds(DateTime::MakeDatetime($datetime_parse_tz("2019-09-16 00:00:00 Europe/Moscow"))) AS md_ms7 -- 1568581200
+```
+
+Converting seconds (in the GMT timezone) to a string date (in the Moscow timezone):
+
+```yql
+$date_format = DateTime::Format("%Y-%m-%d %H:%M:%S %Z");
+SELECT
+ $date_format(AddTimezone(DateTime::FromSeconds(1568592000), 'Europe/Moscow')) -- "2019-09-16 03:00:00 Europe/Moscow"
+```
+
+Converting seconds (in the Moscow timezone) to a string date (in the Moscow timezone). In this case, the %Z timezone is output for reference: usually, it's not needed because it's "GMT" and might mislead you.
+
+```yql
+$date_format = DateTime::Format("%Y-%m-%d %H:%M:%S %Z");
+SELECT
+ $date_format(DateTime::FromSeconds(1568592000)) -- "2019-09-16 00:00:00 GMT"
+```
+
+Converting seconds (in the GMT timezone) to three-letter days of the week (in the Moscow timezone):
+
+```yql
+SELECT
+ SUBSTRING(DateTime::GetDayOfWeekName(AddTimezone(DateTime::FromSeconds(1568581200), "Europe/Moscow")), 0, 3) -- "Mon"
+```
+
+**Date and time formatting**
+
+Usually a separate named expression is used to format time, but you can do without it:
+
+```yql
+$date_format = DateTime::Format("%Y-%m-%d %H:%M:%S %Z");
+
+SELECT
+
+ -- A variant with a named expression
+
+ $date_format(AddTimezone(DateTime::FromSeconds(1568592000), 'Europe/Moscow')),
+
+ -- A variant without a named expression
+
+ DateTime::Format("%Y-%m-%d %H:%M:%S %Z")
+ (AddTimezone(DateTime::FromSeconds(1568592000), 'Europe/Moscow'))
+;
+```
+
+**Converting types**
+
+This way, you can convert only constants:
+
+```yql
+SELECT
+ TzDateTime("2019-09-16T00:00:00,Europe/Moscow"), -- 2019-09-16T00:00:00,Europe/Moscow
+ Date("2019-09-16") -- 2019-09-16
+```
+
+But this way, you can convert a constant, a named expression, or a table field:
+
+```yql
+SELECT
+ CAST("2019-09-16T00:00:00,Europe/Moscow" AS TzDateTime), -- 2019-09-16T00:00:00,Europe/Moscow
+ CAST("2019-09-16" AS Date) -- 2019-09-16
+```
+
+**Converting time to date**
+
+A CAST to Date or TzDate outputs a GMT date for a midnight, local time (for example, for Moscow time 2019-10-22 00:00:00, the date 2019-10-21 is returned). To get a date in the local timezone, you can use DateTime::Format.
+
+```yql
+$x = DateTime("2019-10-21T21:00:00Z");
+select
+ AddTimezone($x, "Europe/Moscow"), -- 2019-10-22T00:00:00,Europe/Moscow
+ cast($x as TzDate), -- 2019-10-21,GMT
+ cast(AddTimezone($x, "Europe/Moscow") as TzDate), -- 2019-10-21,Europe/Moscow
+ cast(AddTimezone($x, "Europe/Moscow") as Date), -- 2019-10-21
+ DateTime::Format("%Y-%m-%d %Z")(AddTimezone($x, "Europe/Moscow")), -- 2019-10-22 Europe/Moscow
+```
+
+**Daylight saving time**
+
+Please note that daylight saving time depends on the year:
+
+```yql
+SELECT
+ RemoveTimezone(TzDatetime("2019-09-16T10:00:00,Europe/Moscow")) as DST1, -- 2019-09-16T07:00:00Z
+ RemoveTimezone(TzDatetime("2008-12-03T10:00:00,Europe/Moscow")) as DST2, -- 2008-12-03T07:00:00Z
+ RemoveTimezone(TzDatetime("2008-07-03T10:00:00,Europe/Moscow")) as DST3, -- 2008-07-03T06:00:00Z (DST)
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/digest.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/digest.md
new file mode 100644
index 00000000000..f861fe8c7cf
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/digest.md
@@ -0,0 +1,39 @@
+# Digest
+
+A set of commonly used hash functions.
+
+**List of functions**
+
+* ```Digest::Crc32c(String{Flags::AutoMap}) -> Uint32```
+* ```Digest::Fnv32(String{Flags::AutoMap}) -> Uint32```
+* ```Digest::Fnv64(String{Flags::AutoMap}) -> Uint64```
+* ```Digest::MurMurHash(String{Flags:AutoMap}) -> Uint64```
+* ```Digest::CityHash(String{Flags:AutoMap}) -> Uint64```
+* ```Digest::CityHash128(String{Flags:AutoMap}) -> Tuple<Uint64,Uint64>```
+* ```Digest::NumericHash(Uint64{Flags:AutoMap}) -> Uint64```
+* ```Digest::Md5Hex(String{Flags:AutoMap}) -> String```
+* ```Digest::Md5Raw(String{Flags:AutoMap}) -> String```
+* ```Digest::Md5HalfMix(String{Flags:AutoMap}) -> Uint64```: MD5 coarsening option (yabs_md5)
+* ```Digest::Argon2(String{Flags:AutoMap},String{Flags:AutoMap}) -> String```: The second argument is the salt
+* ```Digest::Blake2B(String{Flags:AutoMap},[String?]) -> String```: The second optional argument is the key
+* ```Digest::SipHash(Uint64,Uint64,String{Flags:AutoMap}) -> Uint64```
+* ```Digest::HighwayHash(Uint64,Uint64,Uint64,Uint64,String{Flags:AutoMap}) -> Uint64```
+* ```Digest::FarmHashFingerprint(Uint64{Flags:AutoMap}) -> Uint64```
+* ```Digest::FarmHashFingerprint2(Uint64{Flags:AutoMap}, Uint64{Flags:AutoMap}) -> Uint64```
+* ```Digest::FarmHashFingerprint32(String{Flags:AutoMap}) -> Uint32```
+* ```Digest::FarmHashFingerprint64(String{Flags:AutoMap}) -> Uint64```
+* ```Digest::FarmHashFingerprint128(String{Flags:AutoMap}) -> Tuple<Uint64,Uint64>```
+* ```Digest::SuperFastHash(String{Flags:AutoMap}) -> Uint32```
+* ```Digest::Sha1(String{Flags:AutoMap}) -> String```
+* ```Digest::Sha256(String{Flags:AutoMap}) -> String```
+* ```Digest::IntHash64(Uint64{Flags:AutoMap}) -> Uint64```
+* ```Digest::XXH3(String{Flags:AutoMap}) -> Uint64```
+* ```Digest::XXH3_128(String{Flags:AutoMap}) -> Tuple<Uint64,Uint64>```
+
+**Examples**
+
+```sql
+SELECT Digest::Md5Hex("YQL"); -- "1a0c1b56e9d617688ee345da4030da3c"
+SELECT Digest::NumericHash(123456789); -- 1734215268924325803
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/histogram.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/histogram.md
new file mode 100644
index 00000000000..921030daeb7
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/histogram.md
@@ -0,0 +1,2 @@
+
+{% include[x](_includes/histogram.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/hyperscan.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/hyperscan.md
new file mode 100644
index 00000000000..d12f1046a85
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/hyperscan.md
@@ -0,0 +1,127 @@
+# Hyperscan
+
+[Hyperscan](https://www.hyperscan.io) is an opensource library for regular expression matching developed by Intel.
+
+The library includes 4 implementations that use different sets of processor instructions (SSE3, SSE4.2, AVX2, and AVX512), with the needed instruction automatically selected based on the current processor.
+
+By default, all functions work in the single-byte mode. However, if the regular expression is a valid UTF-8 string but is not a valid ASCII string, the UTF-8 mode is enabled automatically.
+
+**List of functions**
+
+* ```Hyperscan::Grep(String) -> (String?) -> Bool```
+* ```Hyperscan::Match(String) -> (String?) -> Bool```
+* ```Hyperscan::BacktrackingGrep(String) -> (String?) -> Bool```
+* ```Hyperscan::BacktrackingMatch(String) -> (String?) -> Bool```
+* ```Hyperscan::MultiGrep(String) -> (String?) -> Tuple<Bool, Bool, ...>```
+* ```Hyperscan::MultiMatch(String) -> (String?) -> Tuple<Bool, Bool, ...>```
+* ```Hyperscan::Capture(String) -> (String?) -> String?```
+* ```Hyperscan::Replace(String) -> (String?, String) -> String?```
+
+## Call syntax {#syntax}
+
+To avoid compiling a regular expression at each table row at direct call, wrap the function call by [a named expression](../../syntax/expressions.md#named-nodes):
+
+```sql
+$re = Hyperscan::Grep("\\d+"); -- create a callable value to match a specific regular expression
+SELECT * FROM table WHERE $re(key); -- use it to filter the table
+```
+
+**Please note** escaping of special characters in regular expressions. Be sure to use the second slash, since all the standard string literals in SQL can accept C-escaped strings, and the `\d` sequence is not valid sequence (even if it were, it wouldn't search for numbers as intended).
+
+You can enable the case-insensitive mode by specifying, at the beginning of the regular expression, the flag `(?i)`.
+
+## Grep {#grep}
+
+Matches the regular expression with a **part of the string** (arbitrary substring).
+
+You can call the `Hyperscan::Grep` function by using a `REGEXP` expression (see the [basic expression syntax](../../syntax/expressions.md#regexp)).
+
+For example, the following two queries are equivalent (also in terms of computing efficiency):
+
+* ```$grep = Hyperscan::Grep("b+"); SELECT $grep("aaabccc");```
+* ```SELECT "aaabccc" REGEXP "b+";```
+
+## Match {#match}
+
+Matches **the whole string** against the regular expression.
+
+To get a result similar to `Grep` (where substring matching is included), enclose the regular expression in `.*` (`.*foo.*` instead of `foo`). However, in terms of code readability, it's usually better to change the function.
+
+## BacktrackingGrep/BacktrackingMatch {#backtrackinggrep}
+
+The functions are identical to the same-name functions without the `Backtracking` prefix. However, they support a broader range of regular expressions. This is due to the fact that if a specific regular expression is not fully supported by Hyperscan, the library switches to the prefilter mode. In this case, it responds not by "Yes" or "No", but by "Definitely not" or "Maybe yes". The "Maybe yes" responses are then automatically rechecked using a slower, but more functional, library [libpcre](https://www.pcre.org).
+
+Those functions are currently called in the binary operators [REGEXP](../../syntax/expressions.md#regexp) and [MATCH](../../syntax/expressions.md#match).
+
+## MultiGrep/MultiMatch {#multigrep}
+
+Hyperscan lets you match against multiple regular expressions in a single pass through the text, and get a separate response for each match.
+
+However, if you want to match a string against any of the listed expressions (the results would be joined with "or"), it would be more efficient to combine the query parts in a single regular expression with `|` and match it with regular `Grep` or `Match`.
+
+When you call `MultiGrep`/`MultiMatch`, regular expressions are passed one per line using [multiline string literals](../../syntax/expressions.md#named-nodes):
+
+**Example**
+
+```sql
+$multi_match = Hyperscan::MultiMatch(@@a.*
+.*x.*
+.*axa.*@@);
+
+SELECT
+ $multi_match("a") AS a,
+ $multi_match("axa") AS axa;
+
+/*
+- a: `(true, false, false)`
+- axa: `(true, true, true)`
+*/
+```
+
+## Capture and Replace {#capture}
+
+Hyperscan doesn't support advanced functionality for such operations. Although `Hyperscan::Capture` and `Hyperscan::Replace` are implemented for consistency, it's better to use the same-name functions from the Re2 library for any non-trivial capture and replace:
+
+* [Re2::Capture](re2.md#capture);
+* [Re2::Replace](re2.md#replace).
+
+## Usage example
+
+```sql
+$value = "xaaxaaXaa";
+
+$match = Hyperscan::Match("a.*");
+$grep = Hyperscan::Grep("axa");
+$insensitive_grep = Hyperscan::Grep("(?i)axaa$");
+$multi_match = Hyperscan::MultiMatch(@@a.*
+.*a.*
+.*a
+.*axa.*@@);
+
+$capture = Hyperscan::Capture(".*a{2}.*");
+$capture_many = Hyperscan::Capture(".*x(a+).*");
+$replace = Hyperscan::Replace("xa");
+
+SELECT
+ $match($value) AS match,
+ $grep($value) AS grep,
+ $insensitive_grep($value) AS insensitive_grep,
+ $multi_match($value) AS multi_match,
+ $multi_match($value).0 AS some_multi_match,
+ $capture($value) AS capture,
+ $capture_many($value) AS capture_many,
+ $replace($value, "b") AS replace
+;
+
+/*
+- match: false
+- grep: true
+- insensitive_grep: true
+- multi_match: (false, true, true, true)
+- some_multi_match: false
+- capture: "xaaa"
+- capture_many: "xaa"
+- replace: "babaXaa"
+*/
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/index.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/index.md
new file mode 100644
index 00000000000..7b4e51e9bd9
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/index.md
@@ -0,0 +1,4 @@
+{% include [x](_includes/index/intro.md) %}
+
+{% include [x](_includes/index/list.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/ip.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/ip.md
new file mode 100644
index 00000000000..ab11e7cd3a7
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/ip.md
@@ -0,0 +1,29 @@
+# Ip
+
+The `Ip` module supports both the IPv4 and IPv6 addresses. By default, they are represented as binary strings of 4 and 16 bytes, respectively.
+
+**List of functions**
+
+* ```Ip::FromString(String{Flags:AutoMap}) -> String?``` - From a human-readable representation to a binary representation.
+* ```Ip::ToString(String{Flags:AutoMap}) -> String?``` - From a binary representation to a human-readable representation.
+* ```Ip::IsIPv4(String?) -> Bool```
+* ```Ip::IsIPv6(String?) -> Bool```
+* ```Ip::IsEmbeddedIPv4(String?) -> Bool```
+* ```Ip::ConvertToIPv6(String{Flags:AutoMap}) -> String```: IPv6 remains unchanged, and IPv4 becomes embedded in IPv6
+* ```Ip::GetSubnet(String{Flags:AutoMap}, [Uint8?]) -> String```: The second argument is the subnet size, by default it's 24 for IPv4 and 64 for IPv6
+
+**Examples**
+
+```sql
+SELECT Ip::IsEmbeddedIPv4(
+ Ip::FromString("::ffff:77.75.155.3")
+); -- true
+
+SELECT
+ Ip::ToString(
+ Ip::GetSubnet(
+ Ip::FromString("213.180.193.3")
+ )
+ ); -- "213.180.193.0"
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/math.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/math.md
new file mode 100644
index 00000000000..65491882657
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/math.md
@@ -0,0 +1,135 @@
+# Math
+
+A set of wrappers around the functions from the libm library and the Yandex utilities.
+
+## Constants {#constants}
+
+**List of functions**
+
+* ```Math::Pi() -> Double```
+* ```Math::E() -> Double```
+
+**Examples**
+
+```sql
+SELECT Math::Pi(); -- 3.141592654
+SELECT Math::E(); -- 2.718281828
+```
+
+## (Double) -> Bool {#double-bool}
+
+**List of functions**
+
+* ```Math::IsInf(Double{Flags:AutoMap}) -> Bool```
+* ```Math::IsNaN(Double{Flags:AutoMap}) -> Bool```
+* ```Math::IsFinite(Double{Flags:AutoMap}) -> Bool```
+
+**Examples**
+
+```sql
+SELECT Math::IsNaN(0.0/0.0); -- true
+SELECT Math::IsFinite(1.0/0.0); -- false
+```
+
+## (Double) -> Double {#double-double}
+
+**List of functions**
+
+* ```Math::Abs(Double{Flags:AutoMap}) -> Double```
+* ```Math::Acos(Double{Flags:AutoMap}) -> Double```
+* ```Math::Asin(Double{Flags:AutoMap}) -> Double```
+* ```Math::Asinh(Double{Flags:AutoMap}) -> Double```
+* ```Math::Atan(Double{Flags:AutoMap}) -> Double```
+* ```Math::Cbrt(Double{Flags:AutoMap}) -> Double```
+* ```Math::Ceil(Double{Flags:AutoMap}) -> Double```
+* ```Math::Cos(Double{Flags:AutoMap}) -> Double```
+* ```Math::Cosh(Double{Flags:AutoMap}) -> Double```
+* ```Math::Erf(Double{Flags:AutoMap}) -> Double```
+* ```Math::Exp(Double{Flags:AutoMap}) -> Double```
+* ```Math::Exp2(Double{Flags:AutoMap}) -> Double```
+* ```Math::Fabs(Double{Flags:AutoMap}) -> Double```
+* ```Math::Floor(Double{Flags:AutoMap}) -> Double```
+* ```Math::Lgamma(Double{Flags:AutoMap}) -> Double```
+* ```Math::Rint(Double{Flags:AutoMap}) -> Double```
+* ```Math::Sigmoid(Double{Flags:AutoMap}) -> Double```
+* ```Math::Sin(Double{Flags:AutoMap}) -> Double```
+* ```Math::Sinh(Double{Flags:AutoMap}) -> Double```
+* ```Math::Sqrt(Double{Flags:AutoMap}) -> Double```
+* ```Math::Tan(Double{Flags:AutoMap}) -> Double```
+* ```Math::Tanh(Double{Flags:AutoMap}) -> Double```
+* ```Math::Tgamma(Double{Flags:AutoMap}) -> Double```
+* ```Math::Trunc(Double{Flags:AutoMap}) -> Double```
+* ```Math::Log(Double{Flags:AutoMap}) -> Double```
+* ```Math::Log2(Double{Flags:AutoMap}) -> Double```
+* ```Math::Log10(Double{Flags:AutoMap}) -> Double```
+
+**Examples**
+
+```sql
+SELECT Math::Sqrt(256); -- 16
+SELECT Math::Trunc(1.2345); -- 1
+```
+
+## (Double, Double) -> Double {#doubledouble-double}
+
+**List of functions**
+
+* ```Math::Atan2(Double{Flags:AutoMap}, Double{Flags:AutoMap}) -> Double```
+* ```Math::Fmod(Double{Flags:AutoMap}, Double{Flags:AutoMap}) -> Double```
+* ```Math::Hypot(Double{Flags:AutoMap}, Double{Flags:AutoMap}) -> Double```
+* ```Math::Pow(Double{Flags:AutoMap}, Double{Flags:AutoMap}) -> Double```
+* ```Math::Remainder(Double{Flags:AutoMap}, Double{Flags:AutoMap}) -> Double```
+
+**Examples**
+
+```sql
+SELECT Math::Atan2(1, 0); -- 1.570796327
+SELECT Math::Remainder(2.1, 2); -- 0.1
+```
+
+## (Double, Int32) -> Double {#doubleint32-double}
+
+**List of functions**
+
+* ```Math::Ldexp(Double{Flags:AutoMap}, Int32{Flags:AutoMap}) -> Double```
+* ```Math::Round(Double{Flags:AutoMap}, [Int32?]) -> Double```: The second argument indicates the power of 10 to which we round (it's negative for decimal digits and positive for rounding to tens, thousands, or millions); the default value is 0
+
+**Examples**
+
+```sql
+SELECT Math::Pow(2, 10); -- 1024
+SELECT Math::Round(1.2345, -2); -- 1.23
+```
+
+## (Double, Double, \[Double?\]) -> Bool {#doubledouble-bool}
+
+**List of functions**
+
+* ```Math::FuzzyEquals(Double{Flags:AutoMap}, Double{Flags:AutoMap}, [Double?]) -> Bool```: Compares two Doubles for being inside the neighborhood specified by the third argument; the default value is 1.0e-13
+
+**Examples**
+
+```sql
+SELECT Math::FuzzyEquals(1.01, 1.0, 0.05); -- true
+```
+
+## Functions for computing remainders
+
+**List of functions**
+
+* ```Math::Mod(Int64{Flags:AutoMap}, Int64) -> Int64?```
+* ```Math::Rem(Int64{Flags:AutoMap}, Int64) -> Int64?```
+
+These functions behave similarly to the built-in % operator in the case of non-negative arguments. The differences are noticeable in the case of negative arguments:
+
+* Math::Mod preserves the sign of the second argument (the denominator).
+* Math::Rem preserves the sign of the first argument (the numerator).
+Functions return null if the divisor is zero.
+
+**Examples**
+
+```sql
+SELECT Math::Mod(-1, 7); -- 6
+SELECT Math::Rem(-1, 7); -- -1
+```
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/pcre.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/pcre.md
new file mode 100644
index 00000000000..9a8f362c2a3
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/pcre.md
@@ -0,0 +1,20 @@
+# Pcre
+
+The Pcre library is currently an alias to [Hyperscan](hyperscan.md).
+
+{% if tech or feature_mapreduce %}
+If you depend on some features of a certain regular expression engine, it's better to internally implement UDF with a given library inside. Use Pcre as the current most-recommended option for simple matching (that can be potentially changed to something else).
+{% endif %}
+
+Currently available engines:
+
+* [Hyperscan](hyperscan.md) <span style="color: gray;">(Intel)</span>
+* [Re2](re2.md) <span style="color: gray;">(Google)</span>
+* [Pire](pire.md) <span style="color: gray;">(Yandex)</span>
+
+Hyperscan and Pire are best-suited for Grep and Match. Inside Hyperscan, there are several implementations that use different sets of processor instructions, with the relevant instruction automatically selected based on the current processor. Pire is also known for its excellent performance. So, if you need high performance, test-run this library against your data and regular expressions. However, since the library almost hasn't been developed since 2011-2013 and its name says "Perl incompatible", you may need to adapt your regular expressions a bit.
+
+The main benefit of the Re2 is its advanced Capture and Replace functionality. Use this library, if you need those functions.
+
+In HyperScan, some functions support backtracking (referencing the previously found part of the string). Those functions are implemented through hybrid use of the two libraries: Hyperscan and libpcre.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/pire.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/pire.md
new file mode 100644
index 00000000000..e608f6b6c65
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/pire.md
@@ -0,0 +1,130 @@
+# Pire
+
+**List of functions**
+
+* ```Pire::Grep(String) -> (String?) -> Bool```
+* ```Pire::Match(String) -> (String?) -> Bool```
+* ```Pire::MultiGrep(String) -> (String?) -> Tuple<Bool, Bool, ...>```
+* ```Pire::MultiMatch(String) -> (String?) -> Tuple<Bool, Bool, ...>```
+* ```Pire::Capture(String) -> (String?) -> String?```
+* ```Pire::Replace(String) -> (String?, String) -> String?```
+
+One of the options to match regular expressions in YQL is to use [Pire](https://github.com/yandex/pire) (Perl Incompatible Regular Expressions). This is a very fast library of regular expressions developed at Yandex: at the lower level, it looks up the input string once, without any lookaheads or rollbacks, spending 5 machine instructions per character (on x86 and x86_64).
+
+The speed is achieved by using the reasonable restrictions:
+
+* Pire is primarily focused at checking whether a string matches a regular expression.
+* The matching substring can also be returned (by Capture), but with restrictions (a match with only one group is returned).
+
+By default, all functions work in the single-byte mode. However, if the regular expression is a valid UTF-8 string but is not a valid ASCII string, the UTF-8 mode is enabled automatically.
+
+To enable the Unicode mode, you can put one character that's beyond ASCII with the `?` operator, for example: `\\w+я?`.
+
+## Call syntax {#call-syntax}
+
+To avoid compiling a regular expression at each table row, wrap the function call by [a named expression](../../syntax/expressions.md#named-nodes):
+
+```sql
+$re = Pire::Grep("\\d+"); -- create a callable value to match a specific regular expression
+SELECT * FROM table WHERE $re(key); -- use it to filter the table
+```
+
+{% note alert %}
+
+When escaping special characters in a regular expression, be sure to use the second slash, since all the standard string literals in SQL can accept C-escaped strings, and the `\d` sequence is not a valid sequence (even if it were, it wouldn't search for numbers as intended).
+
+{% endnote %}
+
+You can enable the case-insensitive mode by specifying, at the beginning of the regular expression, the flag `(?i)`.
+
+**Examples**
+
+```sql
+$value = "xaaxaaxaa";
+$match = Pire::Match("a.*");
+$grep = Pire::Grep("axa");
+$insensitive_grep = Pire::Grep("(?i)axa");
+$multi_match = Pire::MultiMatch(@@a.*
+.*a.*
+.*a
+.*axa.*@@);
+$capture = Pire::Capture(".*x(a).*");
+$capture_many = Pire::Capture(".*x(a+).*");
+$replace = Pire::Replace(".*x(a).*");
+
+SELECT
+ $match($value) AS match,
+ $grep($value) AS grep,
+ $insensitive_grep($value) AS insensitive_grep,
+ $multi_match($value) AS multi_match,
+ $multi_match($value).0 AS some_multi_match,
+ $capture($value) AS capture,
+ $capture_many($value) AS capture_many,
+ $replace($value, "b") AS replace;
+
+/*
+- match: `false`
+- grep: `true`
+- insensitive_grep: `true`
+- multi_match: `(false, true, true, true)`
+- some_multi_match: `false`
+- capture: `"a"`
+- capture_many: `"aa"`
+- replace: `"xaaxaaxba"`
+*/
+```
+
+## Grep {#grep}
+
+Matches the regular expression with a **part of the string** (arbitrary substring).
+
+## Match {#match}
+
+Matches **the whole string** against the regular expression.
+To get a result similar to `Grep` (where substring matching is included), enclose the regular expression in `.*`. For example, use `.*foo.*` instead of `foo`.
+
+## MultiGrep/MultiMatch {#multigrep}
+
+Pire lets you match against multiple regular expressions in a single pass through the text and get a separate response for each match.
+Use the MultiGrep/MultiMatch functions to optimize the query execution speed. Be sure to do it carefully, since the size of the state machine used for matching grows exponentially with the number of regular expressions:
+
+* If you want to match a string against any of the listed expressions (the results are joined with "or"), it would be much more efficient to combine the query parts in a single regular expression with `|` and match it using regular Grep or Match.
+* Pire has a limit on the size of the state machine (YQL uses the default value set in the library). If you exceed the limit, the error is raised at the start of the query: `Failed to glue up regexes, probably the finite state machine appeared to be too large`.
+When you call MultiGrep/MultiMatch, regular expressions are passed one per line using [multiline string literals](../../syntax/expressions.md#multiline-string-literals):
+
+**Examples**
+
+```sql
+$multi_match = Pire::MultiMatch(@@a.*
+.*x.*
+.*axa.*@@);
+
+SELECT
+ $multi_match("a") AS a,
+ $multi_match("axa") AS axa;
+
+/*
+- a: `(true, false, false)`
+- axa: `(true, true, true)`
+*/
+```
+
+## Capture {#capture}
+
+If a string matches the specified regular expression, it returns a substring that matches the group enclosed in parentheses in the regular expression.
+Capture is non-greedy: the shortest possible substring is returned.
+
+{% note alert %}
+
+The expression must contain only **one** group in parentheses. `NULL` (empty Optional) is returned in case of no match.
+
+{% endnote %}
+
+If the above limitations and features are unacceptable for some reason, we recommend that you consider [Re2::Capture](re2.md#capture).
+
+## REPLACE {#replace}
+
+Pire doesn't support replace based on a regular expression. `Pire::Replace` implemented in YQL is a simplified emulation using `Capture`. It may run correctly, if the substring occurs more than once in the source string.
+
+As a rule, it's better to use [Re2::Replace](re2.md#replace) instead.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/re2.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/re2.md
new file mode 100644
index 00000000000..726201e1c9d
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/re2.md
@@ -0,0 +1,122 @@
+# Re2
+
+**List of functions**
+
+* ```Re2::Grep(String) -> (String?) -> Bool```
+* ```Re2::Match(String) -> (String?) -> Bool```
+* ```Re2::Capture(String) -> (String?) -> Struct<_1:String?,foo:String?,...>```
+* ```Re2::FindAndConsume(String) -> (String?) -> List<String>```
+* ```Re2::Replace(String) -> (String?, String) -> String?```
+* ```Re2::Count(String) -> (String?) -> Uint32```
+* ```Re2::Options([CaseSensitive:Bool?,DotNl:Bool?,Literal:Bool?,LogErrors:Bool?,LongestMatch:Bool?,MaxMem:Uint64?,NeverCapture:Bool?,NeverNl:Bool?,OneLine:Bool?,PerlClasses:Bool?,PosixSyntax:Bool?,Utf8:Bool?,WordBoundary:Bool?]) -> Struct<CaseSensitive:Bool,DotNl:Bool,Literal:Bool,LogErrors:Bool,LongestMatch:Bool,MaxMem:Uint64,NeverCapture:Bool,NeverNl:Bool,OneLine:Bool,PerlClasses:Bool,PosixSyntax:Bool,Utf8:Bool,WordBoundary:Bool>```
+
+As Pire has certain limitations needed to ensure efficient string matching against regular expressions, it might be too complex or even impossible to use [Pire](pire.md) for some tasks. For such situations, we added another module to support regular expressions based on [google::RE2](https://github.com/google/re2). It offers a broader range of features ([see the official documentation](https://github.com/google/re2/wiki/Syntax)).
+
+By default, the UTF-8 mode is enabled automatically if the regular expression is a valid UTF-8-encoded string, but is not a valid ASCII string. You can manually control the settings of the re2 library, if you pass the result of the `Re2::Options` function as the second argument to other module functions, next to the regular expression.
+
+{% note warning %}
+
+Make sure to double all the backslashes in your regular expressions (if they are within a quoted string): standard string literals are treated as C-escaped strings in SQL. You can also format regular expressions as raw strings `@@regexp@@`: double slashes are not needed in this case.
+
+{% endnote %}
+
+**Examples**
+
+```sql
+$value = "xaaxaaxaa";
+$options = Re2::Options(false AS CaseSensitive);
+$match = Re2::Match("[ax]+\\d");
+$grep = Re2::Grep("a.*");
+$capture = Re2::Capture(".*(?P<foo>xa?)(a{2,}).*");
+$replace = Re2::Replace("x(a+)x");
+$count = Re2::Count("a", $options);
+
+SELECT
+ $match($value) AS match,
+ $grep($value) AS grep,
+ $capture($value) AS capture,
+ $capture($value)._1 AS capture_member,
+ $replace($value, "b\\1z") AS replace,
+ $count($value) AS count;
+
+/*
+- match: `false`
+- grep: `true`
+- capture: `(_0: 'xaaxaaxaa', _1: 'aa', foo: 'x')`
+- capture_member: `"aa"`
+- replace: `"baazaaxaa"`
+- count:: `6`
+*/
+```
+
+## Re2::Grep / Re2::Match {#match}
+
+If you leave out the details of implementation and syntax of regular expressions, those functions are totally similar [to the applicable functions](pire.md#match) from the Pire modules. With other things equal and no specific preferences, we recommend that you use `Pire::Grep or Pire::Match`.
+
+## Re2::Capture {#capture}
+
+Unlike [Pire::Capture](pire.md#capture), `Re2::Capture` supports multiple and named capturing groups.
+Result type: a structure with the fields of the type `String?`.
+
+* Each field corresponds to a capturing group with the applicable name.
+* For unnamed groups, the following names are generated: `_1`, `_2`, etc.
+* The result always includes the `_0` field containing the entire substring matching the regular expression.
+
+For more information about working with structures in YQL, see the [section on containers](../../types/containers.md).
+
+## Re2::FindAndConsume {#findandconsume}
+
+Searches for all occurrences of the regular expression in the passed text and returns a list of values corresponding to the parenthesized part of the regular expression for each occurrence.
+
+## Re2::Replace {#replace}
+
+Works as follows:
+
+* In the input string (first argument), all the non-overlapping substrings matching the regular expression are replaced by the specified string (second argument).
+* In the replacement string, you can use the contents of capturing groups from the regular expression using back-references in the format: `\\1`, `\\2` etc. The `\\0` back-reference stands for the whole substring that matches the regular expression.
+
+## Re2::Count {#count}
+
+Returns the number of non-overlapping substrings of the input string that have matched the regular expression.
+
+## Re2::Options {#options}
+
+Notes on Re2::Options from the official [repository](https://github.com/google/re2/blob/main/re2/re2.h#L595-L617)
+
+| Parameter | Default | Comments |
+| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------------- |
+| CaseSensitive:Bool? | true | match is case-sensitive (regexp can override with (?i) unless in posix_syntax mode) |
+| DotNl:Bool? | false | let `.` match `\n` (default ) |
+| Literal:Bool? | false | interpret string as literal, not regexp |
+| LogErrors:Bool? | true | log syntax and execution errors to ERROR |
+| LongestMatch:Bool? | false | search for longest match, not first match |
+| MaxMem:Uint64? | - | (see below) approx. max memory footprint of RE2 |
+| NeverCapture:Bool? | false | parse all parents as non-capturing |
+| NeverNl:Bool? | false | never match \n, even if it is in regexp |
+| PosixSyntax:Bool? | false | restrict regexps to POSIX egrep syntax |
+| Utf8:Bool? | true | text and pattern are UTF-8; otherwise Latin-1 |
+| The following options are only consulted when PosixSyntax == true. <bt>When PosixSyntax == false, these features are always enabled and cannot be turned off; to perform multi-line matching in that case, begin the regexp with (?m). |
+| PerlClasses:Bool? | false | allow Perl's \d \s \w \D \S \W |
+| WordBoundary:Bool? | false | allow Perl's \b \B (word boundary and not) |
+| OneLine:Bool? | false | ^ and $ only match beginning and end of text |
+
+It is not recommended to use Re2::Options in the code. Most parameters can be replaced with regular expression flags.
+
+**Flag usage examples**
+
+```sql
+$value = "Foo bar FOO"u;
+-- enable case-insensitive mode
+$capture = Re2::Capture(@@(?i)(foo)@@);
+
+SELECT
+ $capture($value) AS capture;
+
+$capture = Re2::Capture(@@(?i)(?P<vasya>FOO).*(?P<banan>bar)@@);
+
+SELECT
+ $capture($value) AS capture;
+```
+
+In both cases, the word VASYA will be found. Using the raw string @@regexp@@ lets you avoid double slashes.
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/string.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/string.md
new file mode 100644
index 00000000000..b5f49d258a8
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/string.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/string.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/toc_base.yaml b/ydb/docs/en/core/yql/reference/yql-core/udf/list/toc_base.yaml
new file mode 100644
index 00000000000..7078f8aeb3b
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/toc_base.yaml
@@ -0,0 +1,16 @@
+items:
+- name: Overview
+ href: index.md
+- { name: Hyperscan, href: hyperscan.md }
+- { name: Pcre, href: pcre.md }
+- { name: Pire, href: pire.md }
+- { name: Re2, href: re2.md }
+- { name: String, href: string.md }
+- { name: Unicode, href: unicode.md }
+- { name: DateTime, href: datetime.md }
+- { name: Url, href: url.md }
+- { name: Ip, href: ip.md }
+- { name: Yson, href: yson.md }
+- { name: Digest, href: digest.md }
+- { name: Math, href: math.md }
+- { name: Histogram, href: histogram.md }
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/toc_i.yaml b/ydb/docs/en/core/yql/reference/yql-core/udf/list/toc_i.yaml
new file mode 100644
index 00000000000..28325999d2f
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/toc_i.yaml
@@ -0,0 +1,2 @@
+items:
+- include: { mode: link, path: toc_base.yaml } \ No newline at end of file
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/unicode.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/unicode.md
new file mode 100644
index 00000000000..60a2d0fc41c
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/unicode.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/unicode.md) %}
+
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/url.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/url.md
new file mode 100644
index 00000000000..f7ed9339654
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/url.md
@@ -0,0 +1,2 @@
+
+{% include [url.md](_includes/url.md) %}
diff --git a/ydb/docs/en/core/yql/reference/yql-core/udf/list/yson.md b/ydb/docs/en/core/yql/reference/yql-core/udf/list/yson.md
new file mode 100644
index 00000000000..7d7f925cb67
--- /dev/null
+++ b/ydb/docs/en/core/yql/reference/yql-core/udf/list/yson.md
@@ -0,0 +1,295 @@
+# Yson
+
+{% include [_includes/yson/intro_header.md](_includes/yson/intro_header.md) %}
+
+* Similarities with JSON:
+ * Does not have a strict scheme.
+ * Besides simple data types, it supports dictionaries and lists in arbitrary combinations.
+* Some differences from JSON:
+ * It also has a binary representation in addition to the text representation.
+ * The text representation uses semicolons instead of commas and equal signs instead of colons.
+* The concept of "attributes" is supported, that is, named properties that can be assigned to a node in the tree.
+
+Implementation specifics and functionality of the module:
+
+* Along with YSON, this module also supports standard JSON to expand the application scope in a way.
+* It works with a DOM representation of YSON in memory that in YQL terms is passed between functions as a "resource" (see the [description of special data types](../../types/special.md)). Most of the module's functions have the semantics of a query to perform a specified operation with a resource and return an empty [optional](../../types/optional.md) type if the operation failed because the actual data type mismatched the expected one.
+* Provides several main classes of functions (find below a complete list and detailed description of functions):
+ * `Yson::Parse***`: Getting a resource with a DOM object from serialized data, with all further operations performed on the obtained resource.
+ * `Yson::From`: Getting a resource with a DOM object from simple YQL data types or containers (lists or dictionaries).
+ * `Yson::ConvertTo***`: Converting a resource to [primitive data types](../../types/primitive.md) or [containers](../../types/containers.md).
+ * `Yson::Lookup***`: Getting a single list item or a dictionary with optional conversion to the relevant data type.
+ * `Yson::YPath***`: Getting one element from the document tree based on the relative path specified, optionally converting it to the relevant data type.
+ * `Yson::Serialize***`: Getting a copy of data from the resource and serializing the data in one of the formats.
+* For convenience, when serialized Yson and Json are passed to functions expecting a resource with a DOM object, implicit conversion using `Yson::Parse` or `Yson::ParseJson` is done automatically. In SQL syntax, the dot or square brackets operator automatically adds a `Yson::Lookup` call. To serialize a resource, you still need to call `Yson::ConvertTo***` or `Yson::Serialize***`. It means that, for example, to get the "foo" element as a string from the Yson column named mycolumn and serialized as a dictionary, you can write: `SELECT Yson::ConvertToString(mycolumn["foo"]) FROM mytable;` or `SELECT Yson::ConvertToString(mycolumn.foo) FROM mytable;`. In the variant with a dot, special characters can be escaped by [general rules for IDs](../../syntax/expressions.md#escape).
+
+The module's functions must be considered as "building blocks" from which you can assemble different structures, for example:
+
+* `Yson::Parse*** -> Yson::Serialize***`: Converting from one format to other.
+* `Yson::Parse*** -> Yson::Lookup -> Yson::Serialize***`: Extracting the value of the specified subtree in the source YSON tree.
+* `Yson::Parse*** -> Yson::ConvertToList -> ListMap -> Yson::Lookup***`: Extracting items by a key from the YSON list.
+
+{% include [_includes/yson/intro_footer.md](_includes/yson/intro_footer.md) %}
+
+**Examples**
+
+```yql
+$node = Json(@@
+ {"abc": {"def": 123, "ghi": "hello"}}
+@@);
+SELECT Yson::SerializeText($node.abc) AS `yson`;
+-- {"def"=123;"ghi"="\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82"}
+```
+
+```yql
+$node = Yson(@@
+ <a=z;x=y>[
+ {abc=123; def=456};
+ {abc=234; xyz=789};
+ ]
+@@);
+$attrs = Yson::YPath($node, "/@");
+
+SELECT
+ ListMap(Yson::ConvertToList($node), ($x) -> { return Yson::LookupInt64($x, "abc") }) AS abcs,
+ Yson::ConvertToStringDict($attrs) AS attrs,
+ Yson::SerializePretty(Yson::Lookup($node, "7", Yson::Options(false AS Strict))) AS miss;
+
+/*
+- abcs: `[123; 234]`
+- attrs: `{"a"="z";"x"="y"}`
+- miss: `NULL`
+*/
+```
+
+## Yson::Parse... {#ysonparse}
+
+```yql
+Yson::Parse(Yson{Flags:AutoMap}) -> Resource<'Yson2.Node'>
+Yson::ParseJson(Json{Flags:AutoMap}) -> Resource<'Yson2.Node'>
+Yson::ParseJsonDecodeUtf8(Json{Flags:AutoMap}) -> Resource<'Yson2.Node'>
+
+Yson::Parse(String{Flags:AutoMap}) -> Resource<'Yson2.Node'>? -- accepts YSON in any format
+Yson::ParseJson(String{Flags:AutoMap}) -> Resource<'Yson2.Node'>?
+Yson::ParseJsonDecodeUtf8(String{Flags:AutoMap}) -> Resource<'Yson2.Node'>?
+```
+
+The result of all three functions is non-serializable: it can only be passed as the input to other function from the Yson library. However, you can't save it to a table or return to the client as a result of the operation: such an attempt results in a typing error. You also can't return it outside [subqueries](../../syntax/select.md): if you need to do this, call [Yson::Serialize](#ysonserialize), and the optimizer will remove unnecessary serialization and deserialization if materialization isn't needed in the end.
+
+{% note info %}
+
+The `Yson::ParseJsonDecodeUtf8` expects that characters outside the ASCII range must be additionally escaped.
+
+{% endnote %}
+
+## Yson::From {#ysonfrom}
+
+```yql
+Yson::From(T) -> Resource<'Yson2.Node'>
+```
+
+`Yson::From` is a polymorphic function that converts most primitive data types and containers (lists, dictionaries, tuples, structures, and so on) into a Yson resource. The source object type must be Yson-compatible. For example, in dictionary keys, you can only use the `String` or `Utf8` data types, but not `String?` or `Utf8?` .
+
+**Example**
+
+```sql
+SELECT Yson::Serialize(Yson::From(TableRow())) FROM table1;
+```
+
+## Yson::WithAttributes
+
+```yql
+Yson::WithAttributes(Resource<'Yson2.Node'>{Flags:AutoMap}, Resource<'Yson2.Node'>{Flags:AutoMap}) -> Resource<'Yson2.Node'>?
+```
+
+Adds attributes (the second argument) to the Yson node (the first argument). The attributes must constitute a map node.
+
+## Yson::Equals
+
+```yql
+Yson::Equals(Resource<'Yson2.Node'>{Flags:AutoMap}, Resource<'Yson2.Node'>{Flags:AutoMap}) -> Bool
+```
+
+Checking trees in memory for equality. The operation is tolerant to the source serialization format and the order of keys in dictionaries.
+
+## Yson::GetHash
+
+```yql
+Yson::GetHash(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Uint64
+```
+
+Calculating a 64-bit hash from an object tree.
+
+## Yson::Is...
+
+```yql
+Yson::IsEntity(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsString(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsDouble(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsUint64(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsInt64(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsBool(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsList(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsDict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+```
+
+Checking that the current node has the appropriate type. The Entity is `#`.
+
+## Yson::GetLength
+
+```yql
+Yson::GetLength(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Uint64?
+```
+
+Getting the number of elements in a list or dictionary.
+
+## Yson::ConvertTo... {#ysonconvertto}
+
+```yql
+Yson::ConvertTo(Resource<'Yson2.Node'>{Flags:AutoMap}, Type<T>) -> T
+Yson::ConvertToBool(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Bool?
+Yson::ConvertToInt64(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Int64?
+Yson::ConvertToUint64(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Uint64?
+Yson::ConvertToDouble(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Double?
+Yson::ConvertToString(Resource<'Yson2.Node'>{Flags:AutoMap}) -> String?
+Yson::ConvertToList(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<Resource<'Yson2.Node'>>
+Yson::ConvertToBoolList(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<Bool>
+Yson::ConvertToInt64List(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<Int64>
+Yson::ConvertToUint64List(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<Uint64>
+Yson::ConvertToDoubleList(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<Double>
+Yson::ConvertToStringList(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<String>
+Yson::ConvertToDict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Resource<'Yson2.Node'>>
+Yson::ConvertToBoolDict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Bool>
+Yson::ConvertToInt64Dict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Int64>
+Yson::ConvertToUint64Dict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Uint64>
+Yson::ConvertToDoubleDict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Double>
+Yson::ConvertToStringDict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,String>
+```
+
+{% note warning %}
+
+These functions do not do implicit type casting by default, that is, the value in the argument must exactly match the function called.
+
+{% endnote %}
+
+`Yson::ConvertTo` is a polymorphic function that converts the data type that is specified in the second argument and supports containers (lists, dictionaries, tuples, structures, and so on) into a Yson resource.
+
+**Example**
+
+```sql
+$data = Yson(@@{
+ "name" = "Anya";
+ "age" = 15u;
+ "params" = {
+ "ip" = "95.106.17.32";
+ "last_time_on_site" = 0.5;
+ "region" = 213;
+ "user_agent" = "Mozilla/5.0"
+ }
+}@@);
+SELECT Yson::ConvertTo($data,
+ Struct<
+ name: String,
+ age: Uint32,
+ params: Dict<String,Yson>
+ >
+);
+```
+
+## Yson::Contains {#ysoncontains}
+
+```yql
+Yson::Contains(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Bool?
+```
+
+Checks for a key in the dictionary. If the object type is a map, then it searches among the keys.
+If the object type is a list, then the key must be a decimal number, i.e., an index in the list.
+
+## Yson::Lookup... {#ysonlookup}
+
+```yql
+Yson::Lookup(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Resource<'Yson2.Node'>?
+Yson::LookupBool(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Bool?
+Yson::LookupInt64(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Int64?
+Yson::LookupUint64(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Uint64?
+Yson::LookupDouble(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Double?
+Yson::LookupString(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> String?
+Yson::LookupDict(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Dict<String,Resource<'Yson2.Node'>>?
+Yson::LookupList(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> List<Resource<'Yson2.Node'>>?
+```
+
+The above functions are short notations for a typical use case: `Yson::YPath`: go to a level in the dictionary and then extract the value — `Yson::ConvertTo***`. For all the listed functions, the second argument is a key name from the dictionary (unlike YPath, it has no `/`prefix) or an index from the list (for example, `7`). They simplify the query and produce a small gain in speed.
+
+## Yson::YPath {#ysonypath}
+
+```yql
+Yson::YPath(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Resource<'Yson2.Node'>?
+Yson::YPathBool(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Bool?
+Yson::YPathInt64(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Int64?
+Yson::YPathUint64(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Uint64?
+Yson::YPathDouble(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Double?
+Yson::YPathString(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> String?
+Yson::YPathDict(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Dict<String,Resource<'Yson2.Node'>>?
+Yson::YPathList(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> List<Resource<'Yson2.Node'>>?
+```
+
+Lets you get a part of the resource based on the source resource and the part's path in YPath format.
+
+{% include [_includes/yson/ypath_overlay.md](_includes/yson/ypath_overlay.md) %}
+
+## Yson::Attributes {#ysonattributes}
+
+```yql
+Yson::Attributes(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Resource<'Yson2.Node'>>
+```
+
+Getting all node attributes as a dictionary.
+
+## Yson::Serialize... {#ysonserialize}
+
+```yql
+Yson::Serialize(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Yson -- A binary representation
+Yson::SerializeText(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Yson
+Yson::SerializePretty(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Yson -- To get a text result, wrap it in ToBytes(...)
+```
+
+## Yson::SerializeJson {#ysonserializejson}
+
+```yql
+Yson::SerializeJson(Resource<'Yson2.Node'>{Flags:AutoMap}, [Resource<'Yson2.Options'>?, SkipMapEntity:Bool?, EncodeUtf8:Bool?]) -> Json?
+```
+
+* `SkipMapEntity` serializes `#` values in dictionaries. The value of attributes is not affected by the flag. By default, `false`.
+* `EncodeUtf8` responsible for escaping non-ASCII characters. By default, `false`.
+
+The `Yson` and `Json` data types returned by serialization functions are special cases of a string that is known to contain data in the given format (Yson/Json).
+
+## Yson::Options {#ysonoptions}
+
+```yql
+Yson::Options([AutoConvert:Bool?, Strict:Bool?]) -> Resource<'Yson2.Options'>
+```
+
+It's passed in the last optional argument (omitted for brevity) to the methods `Parse...`, `ConvertTo...`, `Contains`, `Lookup...`, and `YPath...` that accept the result of the `Yson::Options` call. By default, all the `Yson::Options` fields are false and when enabled (true), they modify the behavior as follows:
+
+* **AutoConvert**: If the value passed to Yson doesn't match the result data type exactly, the value is converted where possible. For example, `Yson::ConvertToInt64` in this mode will convert even Double numbers to Int64.
+* **Strict**: By default, all functions from the Yson library return an error in case of issues during query execution (for example, an attempt to parse a string that is not Yson/Json, or an attempt to search by a key in a scalar type, or when a conversion to an incompatible data type has been requested, and so on). If you disable the strict mode, `NULL` is returned instead of an error in most cases. When converting to a dictionary or list (`ConvertTo<Type>Dict` or `ConvertTo<Type>List`), improper items are excluded from the resulting collection.
+
+**Example:**
+
+```yql
+$yson = @@{y = true; x = 5.5}@@y;
+SELECT Yson::LookupBool($yson, "z"); --- null
+SELECT Yson::LookupBool($yson, "y"); --- true
+
+SELECT Yson::LookupInt64($yson, "x"); --- Error
+SELECT Yson::LookupInt64($yson, "x", Yson::Options(false as Strict)); --- null
+SELECT Yson::LookupInt64($yson, "x", Yson::Options(true as AutoConvert)); --- 5
+
+SELECT Yson::ConvertToBoolDict($yson); --- Error
+SELECT Yson::ConvertToBoolDict($yson, Yson::Options(false as Strict)); --- { "y": true }
+SELECT Yson::ConvertToDoubleDict($yson, Yson::Options(false as Strict)); --- { "x": 5.5 }
+```
+
+If you need to use the same Yson library settings throughout the query, it's more convenient to use [PRAGMA yson.AutoConvert;](../../syntax/pragma.md#yson.autoconvert) and/or [PRAGMA yson.Strict;](../../syntax/pragma.md#yson.strict). Only with these `PRAGMA` you can affect implicit calls to the Yson library occurring when you work with Yson/Json data types.
+
diff --git a/ydb/docs/ru/core/yql/reference/toc_i.yaml b/ydb/docs/ru/core/yql/reference/toc_i.yaml
index c7e699282ba..5ecab61267f 100644
--- a/ydb/docs/ru/core/yql/reference/toc_i.yaml
+++ b/ydb/docs/ru/core/yql/reference/toc_i.yaml
@@ -1,2 +1,2 @@
items:
-- include: { mode: merge, path: ../../../yql/docs_yfm/docs/ru/yql-core/toc_m.yaml }
+- include: { mode: merge, path: yql-core/toc_m.yaml }
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/_includes/cast_examples.md b/ydb/docs/ru/core/yql/reference/yql-core/_includes/cast_examples.md
new file mode 100644
index 00000000000..4e90286bb07
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/_includes/cast_examples.md
@@ -0,0 +1,14 @@
+ SELECT
+ CAST("12345" AS Double), -- 12345.0
+ CAST(1.2345 AS Uint8), -- 1
+ CAST(12345 AS String), -- "12345"
+ CAST("1.2345" AS Decimal(5, 2)), -- 1.23
+ CAST("xyz" AS Uint64) IS NULL, -- true, так как не удалось
+ CAST(-1 AS Uint16) IS NULL, -- true, отрицательное в беззнаковое
+ CAST([-1, 0, 1] AS List<Uint8?>), -- [null, 0, 1]
+ --Тип элемента опциональный: неудачный элемент в null.
+ CAST(["3.14", "bad", "42"] AS List<Float>), -- [3.14, 42]
+ --Тип элемента не опциональный: неудачный элемент удалён.
+ CAST(255 AS Uint8), -- 255
+ CAST(256 AS Uint8) IS NULL -- true, выходит за диапазон
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/_includes/decimal_args.md b/ydb/docs/ru/core/yql/reference/yql-core/_includes/decimal_args.md
new file mode 100644
index 00000000000..1b56d44e701
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/_includes/decimal_args.md
@@ -0,0 +1,4 @@
+Для параметрического типа данных Decimal дополнительно указывается два аргумента:
+
+* общее число десятичных знаков (до 35, включительно);
+* число десятичных знаков после запятой (из общего числа, то есть строго не больше предыдущего аргумента).
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/agg_list.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/agg_list.md
new file mode 100644
index 00000000000..69e04a169bd
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/agg_list.md
@@ -0,0 +1,37 @@
+## AGGREGATE_LIST {#agg-list}
+
+Получить все значения столбца в виде списка. В сочетании с `DISTINCT` возвращает только уникальные значения. Опциональный второй параметр задает максимальное количество получаемых значений.
+
+Если заранее известно, что уникальных значений не много, то лучше воспользоваться агрегатной функцией `AGGREGATE_LIST_DISTINCT`, которая строит тот же результат в памяти (которой при большом числе уникальных значений может не хватить).
+
+Порядок элементов в результирующем списке зависит от реализации и снаружи не задается. Чтобы получить упорядоченный список, необходимо отсортировать результат, например с помощью [ListSort](../../list.md#listsort).
+
+Чтобы получить список нескольких значений с одной строки, важно *НЕ* использовать функцию `AGGREGATE_LIST` несколько раз, а сложить все нужные значения в контейнер, например через [AsList](../../basic.md#aslist) или [AsTuple](../../basic.md#astuple) и передать этот контейнер в один вызов `AGGREGATE_LIST`.
+
+Например, можно использовать в сочетании с `DISTINCT` и функцией [String::JoinFromList](../../../udf/list/string.md) (аналог `','.join(list)` из Python) для распечатки в строку всех значений, которые встретились в столбце после применения [GROUP BY](../../../syntax/group_by.md).
+
+**Примеры**
+
+``` yql
+SELECT
+ AGGREGATE_LIST( region ),
+ AGGREGATE_LIST( region, 5 ),
+ AGGREGATE_LIST( DISTINCT region ),
+ AGGREGATE_LIST_DISTINCT( region ),
+ AGGREGATE_LIST_DISTINCT( region, 5 )
+FROM users
+```
+
+``` yql
+-- Аналог GROUP_CONCAT из MySQL
+SELECT
+ String::JoinFromList(CAST(AGGREGATE_LIST(region, 2) AS List<String>), ",")
+FROM users
+```
+Существует также короткая форма записи этих функций - `AGG_LIST` и `AGG_LIST_DISTINCT`.
+
+{% note alert %}
+
+Выполняется **НЕ** ленивым образом, поэтому при использовании нужно быть уверенным, что список получится разумных размеров, примерно в пределах тысячи элементов. Чтобы подстраховаться, можно воспользоваться вторым опциональным числовым аргументом, который включает ограничение на число элементов в списке.
+
+{% endnote %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/aggregate_by.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/aggregate_by.md
new file mode 100644
index 00000000000..5456e249963
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/aggregate_by.md
@@ -0,0 +1,23 @@
+
+## AGGREGATE_BY и MULTI_AGGREGATE_BY {#aggregate-by}
+Применение [фабрики агрегационной функции](../../basic.md#aggregationfactory) ко всем значениям колонки или выражения. Функция `MULTI_AGGREGATE_BY` требует, чтобы в значении колонки или выражения была структура, кортеж или список, и применяет фабрику поэлементно, размещая результат в контейнере той же формы. Если в разных значениях колонки или выражения содержатся списки разной длины, результирующий список будет иметь наименьшую из длин этих списков.
+
+1. Колонка, `DISTINCT` колонка или выражение;
+2. Фабрика.
+
+**Примеры:**
+``` yql
+$count_factory = AggregationFactory("COUNT");
+
+SELECT
+ AGGREGATE_BY(DISTINCT column, $count_factory) as uniq_count
+FROM my_table;
+
+SELECT
+ MULTI_AGGREGATE_BY(nums, AggregationFactory("count")) as count,
+ MULTI_AGGREGATE_BY(nums, AggregationFactory("min")) as min,
+ MULTI_AGGREGATE_BY(nums, AggregationFactory("max")) as max,
+ MULTI_AGGREGATE_BY(nums, AggregationFactory("avg")) as avg,
+ MULTI_AGGREGATE_BY(nums, AggregationFactory("percentile", 0.9)) as p90
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/bool_bit.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/bool_bit.md
new file mode 100644
index 00000000000..2042a7cf8b3
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/bool_bit.md
@@ -0,0 +1,25 @@
+## BOOL_AND, BOOL_OR и BOOL_XOR {#bool-and-or-xor}
+
+Применение соответствующей логической операции (`AND`/`OR`/`XOR`) ко всем значениям булевой колонки или выражения.
+
+Эти функции **не пропускают** `NULL` значение при агрегации, единственное `NULL` значение превратит результат в `NULL`. Для агрегации с пропуском `NULL`-ов можно использовать функции `MIN`/`MAX` или `BIT_AND`/`BIT_OR`/`BIT_XOR`.
+
+**Примеры**
+``` yql
+SELECT
+ BOOL_AND(bool_column),
+ BOOL_OR(bool_column),
+ BOOL_XOR(bool_column)
+FROM my_table;
+```
+
+## BIT_AND, BIT_OR и BIT_XOR {#bit-and-or-xor}
+
+Применение соответствующей битовой операции ко всем значениям числовой колонки или выражения.
+
+**Примеры**
+``` yql
+SELECT
+ BIT_XOR(unsigned_numeric_value)
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/corr_covar.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/corr_covar.md
new file mode 100644
index 00000000000..5423b611e6b
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/corr_covar.md
@@ -0,0 +1,25 @@
+## CORRELATION и COVARIANCE {#correlation-covariance}
+
+Корреляция и ковариация двух колонок.
+
+Также доступны сокращенные версии `CORR` или `COVAR`, а для ковариации - версии с суффиксом `SAMPLE` / `POPULATION` по аналогии с описанной выше [VARIANCE](#variance).
+
+В отличие от большинства других агрегатных функций не пропускают `NULL`, а считают его за 0.
+
+При использовании [фабрики агрегационной функции](../../basic.md#aggregationfactory) в качестве первого аргумента [AGGREGATE_BY](#aggregateby) передается `Tuple` из двух значений.
+
+**Примеры**
+``` yql
+SELECT
+ CORRELATION(numeric_column, another_numeric_column),
+ COVARIANCE(numeric_column, another_numeric_column)
+FROM my_table;
+```
+
+``` yql
+$corr_factory = AggregationFactory("CORRELATION");
+
+SELECT
+ AGGREGATE_BY(AsTuple(numeric_column, another_numeric_column), $corr_factory)
+FROM my_table;
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/count_distinct_estimate.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/count_distinct_estimate.md
new file mode 100644
index 00000000000..c1d58199219
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/count_distinct_estimate.md
@@ -0,0 +1,26 @@
+## CountDistinctEstimate, HyperLogLog и HLL {#countdistinctestimate}
+
+Примерная оценка числа уникальных значений по алгоритму [HyperLogLog](https://en.wikipedia.org/wiki/HyperLogLog). Логически делает то же самое, что и [COUNT(DISTINCT ...)](#count), но работает значительно быстрее ценой некоторой погрешности.
+
+Аргументы:
+
+1. Значение для оценки;
+2. Точность (от 4 до 18 включительно, по умолчанию 14).
+
+Выбор точности позволяет разменивать дополнительное потребление вычислительных ресурсов и оперативной памяти на уменьшение погрешности.
+
+На данный момент все три функции являются алиасами, но в будущем `CountDistinctEstimate` может начать использовать другой алгоритм.
+
+**Примеры**
+``` yql
+SELECT
+ CountDistinctEstimate(my_column)
+FROM my_table;
+```
+
+``` yql
+SELECT
+ HyperLogLog(my_column, 4)
+FROM my_table;
+```
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/histogram.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/histogram.md
new file mode 100644
index 00000000000..9ff04d9c505
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/histogram.md
@@ -0,0 +1,113 @@
+## HISTOGRAM {#histogram}
+
+Построение примерной гистограммы по числовому выражению с автоматическим выбором корзин.
+
+[Вспомогательные функции](../../../udf/list/histogram.md)
+
+### Базовые настройки
+
+Ограничение на число корзин можно задать с помощью опционального аргумента, значение по умолчанию — 100. Следует иметь в виду, что дополнительная точность стоит дополнительных вычислительных ресурсов и может негативно сказываться на времени выполнения запроса, а в экстремальных случаях — и на его успешности.
+
+### Поддержка весов
+
+Имеется возможность указать «вес» для каждого значения, участвующего в построении гистограммы. Для этого вторым аргументом в агрегатную функцию нужно передать выражение для вычисления веса. По умолчанию всегда используется вес `1.0`. Если используются нестандартные веса, ограничение на число корзин можно задать третьим аргументом.
+
+В случае, если передано два аргумента, смысл второго аргумента определяется по его типу (целочисленный литерал — ограничение на число корзин, в противном случае — вес).
+
+{% if tech %}
+### Алгоритмы
+
+* [Оригинальный whitepaper](http://jmlr.org/papers/volume11/ben-haim10a/ben-haim10a.pdf);
+
+Доступны разные модификации алгоритма:
+``` yql
+AdaptiveDistanceHistogram
+AdaptiveWeightHistogram
+AdaptiveWardHistogram
+BlockWeightHistogram
+BlockWardHistogram
+```
+
+По умолчанию `HISTOGRAM` является синонимом к `AdaptiveWardHistogram`. Обе функции эквивалентны и взаимозаменимы во всех контекстах.
+
+Алгоритмы Distance, Weight и Ward отличаются формулами объединения двух точек в одну:
+
+``` c++
+ TWeightedValue CalcDistanceQuality(const TWeightedValue& left, const TWeightedValue& right) {
+ return TWeightedValue(right.first - left.first, left.first);
+ }
+
+ TWeightedValue CalcWeightQuality(const TWeightedValue& left, const TWeightedValue& right) {
+ return TWeightedValue(right.second + left.second, left.first);
+ }
+
+ TWeightedValue CalcWardQuality(const TWeightedValue& left, const TWeightedValue& right) {
+ const double N1 = left.second;
+ const double N2 = right.second;
+ const double mu1 = left.first;
+ const double mu2 = right.first;
+ return TWeightedValue(N1 * N2 / (N1 + N2) * (mu1 - mu2) * (mu1 - mu2), left.first);
+ }
+```
+
+Чем отличается Adaptive и Block:
+<blockquote>Contrary to adaptive histogram, block histogram doesn't rebuild bins after the addition of each point. Instead, it accumulates points and in case the amount of points overflows specified limits, it shrinks all the points at once to produce histogram. Indeed, there exist two limits and two shrinkage operations:
+
+1. FastGreedyShrink is fast but coarse. It is used to shrink from upper limit to intermediate limit (override FastGreedyShrink to set specific behaviour).
+2. SlowShrink is slow, but produces finer histogram. It shrinks from the intermediate limit to the actual number of bins in a manner similar to that in adaptive histogram (set CalcQuality in 34constuctor)
+While FastGreedyShrink is used most of the time, SlowShrink is mostly used for histogram finalization
+</blockquote>
+{% endif %}
+
+### Если нужна точная гистограмма
+
+1. Можно воспользоваться описанными ниже агрегатными функциями с фиксированными сетками корзин: [LinearHistogram](#linearhistogram) или [LogarithmicHistogram](#logarithmichistogram).
+2. Можно самостоятельно вычислить номер корзины для каждой строки и сделать по нему [GROUP BY](../../../syntax/group_by.md).
+
+При использовании [фабрики агрегационной функции](../../basic.md#aggregationfactory) в качестве первого аргумента [AGGREGATE_BY](#aggregateby) передается `Tuple` из значения и веса.
+
+**Примеры**
+``` yql
+SELECT
+ HISTOGRAM(numeric_column)
+FROM my_table;
+```
+
+``` yql
+SELECT
+ Histogram::Print(
+ HISTOGRAM(numeric_column, 10),
+ 50
+ )
+FROM my_table;
+```
+
+```yql
+$hist_factory = AggregationFactory("HISTOGRAM");
+
+SELECT
+ AGGREGATE_BY(AsTuple(numeric_column, 1.0), $hist_factory)
+FROM my_table;
+```
+
+## LinearHistogram, LogarithmicHistogram и LogHistogram {#linearhistogram}
+
+Построение гистограммы по явно указанной фиксированной шкале корзин.
+
+Аргументы:
+
+1. Выражение, по значению которого строится гистограмма. Все последующие — опциональны.
+2. Расстояние между корзинами для `LinearHistogram` или основание логарифма для `LogarithmicHistogram` / `LogHistogram` (это алиасы). В обоих случаях значение по умолчанию — 10.
+3. Минимальное значение. По умолчанию минус бесконечность.
+4. Максимальное значение. По умолчанию плюс бесконечность.
+
+Формат результата полностью аналогичен [адаптивным гистограммам](#histogram), что позволяет использовать тот же [набор вспомогательных функций](../../../udf/list/histogram.md).
+
+Если разброс входных значений неконтролируемо велик, рекомендуется указывать минимальное и максимальное значение для предотвращения потенциальных падений из-за высокого потребления памяти.
+
+**Примеры**
+``` yql
+SELECT
+ LogarithmicHistogram(numeric_column, 2)
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/max_min_by.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/max_min_by.md
new file mode 100644
index 00000000000..1d4b3e91e4c
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/max_min_by.md
@@ -0,0 +1,38 @@
+## MAX_BY и MIN_BY {#max-min-by}
+
+Вернуть значение первого аргумента для строки таблицы, в которой второй аргумент оказался минимальным/максимальным.
+
+Опционально можно указать третий аргумент N, который влияет на поведение в случае, если в таблице есть несколько строк с одинаковым минимальным или максимальным значением:
+
+* Если N не указано — будет возвращено значение одной из строк, а остальные отбрасываются.
+* Если N указано — будет возвращен список со всеми значениями, но не более N, все значения после достижения указанного числа отбрасываются.
+
+При выборе значения N рекомендуется не превышать порядка сотен или тысяч, чтобы не возникало проблем с ограниченной доступной памятью на кластерах {{ backend_name }}.
+
+Если для задачи обязательно нужны все значения, и их количество может измеряться десятками тысяч и больше, то вместо данных агрегационных функций следует использовать `JOIN` исходной таблицы с подзапросом, где по ней же сделан `GROUP BY + MIN/MAX` на интересующих вас колонках.
+
+{% note warning "Внимание" %}
+
+Если второй аргумент всегда NULL, то результатом агрегации будет NULL.
+
+{% endnote %}
+
+При использовании [фабрики агрегационной функции](../../basic.md#aggregationfactory) в качестве первого аргумента [AGGREGATE_BY](#aggregateby) передается `Tuple` из значения и ключа.
+
+**Примеры**
+``` yql
+SELECT
+ MIN_BY(value, LENGTH(value)),
+ MAX_BY(value, key, 100)
+FROM my_table;
+```
+
+``` yql
+$min_by_factory = AggregationFactory("MIN_BY");
+$max_by_factory = AggregationFactory("MAX_BY", 100);
+
+SELECT
+ AGGREGATE_BY(AsTuple(value, LENGTH(value)), $min_by_factory),
+ AGGREGATE_BY(AsTuple(value, key), $max_by_factory)
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/percentile_median.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/percentile_median.md
new file mode 100644
index 00000000000..14de5a2415c
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/percentile_median.md
@@ -0,0 +1,17 @@
+## PERCENTILE и MEDIAN {#percentile-median}
+
+Подсчет процентилей по амортизированной версии алгоритма [TDigest](https://github.com/tdunning/t-digest). `MEDIAN` — алиас для `PERCENTILE(N, 0.5)`.
+
+{% note info "Ограничение" %}
+
+Первый аргумент (N) должен быть именем колонки таблицы. Если это ограничение необходимо обойти, можно использовать подзапрос. Ограничение введено для упрощения вычислений, поскольку в реализации несколько вызовов с одинаковым первым аргументом (N) склеиваются в один проход.
+
+{% endnote %}
+
+``` yql
+SELECT
+ MEDIAN(numeric_column),
+ PERCENTILE(numeric_column, 0.99)
+FROM my_table;
+```
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/session_start.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/session_start.md
new file mode 100644
index 00000000000..c8236bd7704
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/session_start.md
@@ -0,0 +1,6 @@
+## SessionStart {#session-start}
+
+Без аргументов. Допускается только при наличии [SessionWindow](../../../syntax/group_by.md#session-window) в
+[GROUP BY](../../../syntax/group_by.md) / [PARTITION BY](../../../syntax/window.md#partition).
+Возвращает значение ключевой колонки `SessionWindow`. В случае `SessionWindow` с двумя аргументами – минимальное значение первого аргумента внутри группы/раздела.
+В случае раширенного варианта `SessionWindoow` – значение второго элемента кортежа, возвращаемого `<calculate_lambda>`, при котором первый элемент кортежа равен `True`.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/simple.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/simple.md
new file mode 100644
index 00000000000..0edf5e0d4df
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/simple.md
@@ -0,0 +1,125 @@
+## COUNT {#count}
+
+Подсчет количества строк в таблице (если в качестве аргумента указана `*` или константа) или непустых значений в столбце таблицы (если в качестве аргумента указано имя столбца).
+
+Как и другие агрегатные функции, может использоваться в сочетании с [GROUP BY](../../../syntax/group_by.md) для получения статистики по частям таблицы, соответствующим значениям в столбцах, по которым идет группировка. {% if select_statement != "SELECT STREAM" %}А модификатор [DISTINCT](../../../syntax/group_by.md#distinct) позволяет посчитать число уникальных значений.{% endif %}
+
+**Примеры**
+``` yql
+SELECT COUNT(*) FROM my_table;
+```
+
+``` yql
+SELECT key, COUNT(value) FROM my_table GROUP BY key;
+```
+{% if select_statement != "SELECT STREAM" %}
+
+``` yql
+SELECT COUNT(DISTINCT value) FROM my_table;
+```
+{% endif %}
+
+## MIN и MAX {#min-max}
+
+Минимальное или максимальное значение.
+
+В качестве аргумента допустимо произвольное вычислимое выражение с числовым результатом.
+
+**Примеры**
+``` yql
+SELECT MIN(value), MAX(value) FROM my_table;
+```
+
+## SUM {#sum}
+
+Сумма чисел.
+
+В качестве аргумента допустимо произвольное вычислимое выражение с числовым результатом.
+
+Целые числа автоматически расширяются до 64 бит, чтобы уменьшить риск переполнения.
+
+``` yql
+SELECT SUM(value) FROM my_table;
+```
+
+## AVG {#avg}
+
+Арифметическое среднее.
+
+В качестве аргумента допустимо произвольное вычислимое выражение с числовым результатом.
+
+Целочисленные значения и интервалы времени автоматически приводятся к Double.
+
+**Примеры**
+``` yql
+SELECT AVG(value) FROM my_table;
+```
+
+## COUNT_IF {#count-if}
+
+Количество строк, для которых указанное в качестве аргумента выражение истинно (результат вычисления выражения — true).
+
+Значение `NULL` приравнивается к `false` (в случае, если тип аргумента `Bool?`).
+
+Функция *не* выполняет неявного приведения типов к булевым для строк и чисел.
+
+**Примеры**
+``` yql
+SELECT
+ COUNT_IF(value % 2 == 1) AS odd_count
+```
+
+{% if select_statement != "SELECT STREAM" %}
+{% note info %}
+
+Если нужно посчитать число уникальных значений на строках, где выполняется условие, то в отличие от остальных агрегатных функций модификатор [DISTINCT](../../../syntax/group_by.md#distinct) тут не поможет, так как в аргументах нет никаких значений. Для получения данного результата, стоит воспользоваться в подзапросе встроенной функцией [IF](../../../builtins/basic.md#if) с двумя аргументами (чтобы в else получился `NULL`), а снаружи сделать [COUNT(DISTINCT ...)](#count) по её результату.
+
+{% endnote %}
+{% endif %}
+
+## SUM_IF и AVG_IF {#sum-if}
+
+Сумма или арифметическое среднее, но только для строк, удовлетворяющих условию, переданному вторым аргументом.
+
+Таким образом, `SUM_IF(value, condition)` является чуть более короткой записью для `SUM(IF(condition, value))`, аналогично для `AVG`. Расширение типа данных аргумента работает так же аналогично одноименным функциям без суффикса.
+
+**Примеры**
+``` yql
+SELECT
+ SUM_IF(value, value % 2 == 1) AS odd_sum,
+ AVG_IF(value, value % 2 == 1) AS odd_avg,
+FROM my_table;
+```
+
+При использовании [фабрики агрегационной функции](../../basic.md#aggregationfactory) в качестве первого аргумента [AGGREGATE_BY](#aggregateby) передается `Tuple` из значения и предиката.
+
+**Примеры**
+
+``` yql
+$sum_if_factory = AggregationFactory("SUM_IF");
+$avg_if_factory = AggregationFactory("AVG_IF");
+
+SELECT
+ AGGREGATE_BY(AsTuple(value, value % 2 == 1), $sum_if_factory) AS odd_sum,
+ AGGREGATE_BY(AsTuple(value, value % 2 == 1), $avg_if_factory) AS odd_avg
+FROM my_table;
+```
+
+## SOME {#some}
+
+Получить значение указанного в качестве аргумента выражения для одной из строк таблицы. Не дает никаких гарантий о том, какая именно строка будет использована. Аналог функции [any()]{% if lang == "en" %}(https://clickhouse.tech/docs/en/sql-reference/aggregate-functions/reference/any/){% else %}(https://clickhouse.tech/docs/ru/sql-reference/aggregate-functions/reference/any/){% endif %} в ClickHouse.
+
+Из-за отсутствия гарантий `SOME` вычислительно дешевле, чем часто использующиеся в подобных ситуациях [MIN](#min)/[MAX](#max).
+
+**Примеры**
+``` yql
+SELECT
+ SOME(value)
+FROM my_table;
+```
+
+{% note alert %}
+
+При вызове агрегатной функции `SOME` несколько раз **не** гарантируется, что все значения результатов будут взяты с одной строки исходной таблицы. Для получения данной гарантии, нужно запаковать значения в какой-либо из контейнеров и передавать в `SOME` уже его. Например, для структуры это можно сделать с помощью [AsStruct](../../../builtins/basic.md#asstruct)
+
+{% endnote %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/stddev_variance.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/stddev_variance.md
new file mode 100644
index 00000000000..a5afd135d70
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/stddev_variance.md
@@ -0,0 +1,20 @@
+## STDDEV и VARIANCE {#stddev-variance}
+
+Стандартное отклонение и дисперсия по колонке. Используется [однопроходной параллельный алгоритм](https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Parallel_algorithm), результат которого может отличаться от полученного более распространенными методами, требующими двух проходов по данным.
+
+По умолчанию вычисляются выборочная дисперсия и стандартное отклонение. Доступны несколько способов записи:
+
+* с суффиксом/префиксом `POPULATION`, например: `VARIANCE_POPULATION`, `POPULATION_VARIANCE` — вычисляет дисперсию/стандартное отклонение для генеральной совокупности;
+* с суффиксом/префиксом `SAMPLE` или без суффикса, например `VARIANCE_SAMPLE`, `SAMPLE_VARIANCE`, `SAMPLE` — вычисляет выборочную дисперсию и стандартное отклонение.
+
+Также определено несколько сокращенных алиасов, например `VARPOP` или `STDDEVSAMP`.
+
+Если все переданные значения — `NULL`, возвращает `NULL`.
+
+**Примеры**
+``` yql
+SELECT
+ STDDEV(numeric_column),
+ VARIANCE(numeric_column)
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/top_bottom.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/top_bottom.md
new file mode 100644
index 00000000000..8d83e0f0321
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/top_bottom.md
@@ -0,0 +1,45 @@
+## TOP и BOTTOM {#top-bottom}
+
+Вернуть список максимальных/минимальных значений выражения. Первый аргумент - выражение, второй - ограничение на количество элементов.
+
+**Примеры**
+``` yql
+SELECT
+ TOP(key, 3),
+ BOTTOM(value, 3)
+FROM my_table;
+```
+
+``` yql
+$top_factory = AggregationFactory("TOP", 3);
+$bottom_factory = AggregationFactory("BOTTOM", 3);
+
+SELECT
+ AGGREGATE_BY(key, $top_factory),
+ AGGREGATE_BY(value, $bottom_factory)
+FROM my_table;
+```
+
+## TOP_BY и BOTTOM_BY {#top-bottom-by}
+
+Вернуть список значений первого аргумента для строк с максимальными/минимальными значениями второго аргумента. Третий аргумент - ограничение на количество элементов в списке.
+
+При использовании [фабрики агрегационной функции](../../basic.md#aggregationfactory) в качестве первого аргумента [AGGREGATE_BY](#aggregateby) передается `Tuple` из значения и ключа. Ограничение на количество элементов в этом случае передаётся вторым аргументом при создании фабрики.
+
+**Примеры**
+``` yql
+SELECT
+ TOP_BY(value, LENGTH(value), 3),
+ BOTTOM_BY(value, key, 3)
+FROM my_table;
+```
+
+``` yql
+$top_by_factory = AggregationFactory("TOP_BY", 3);
+$bottom_by_factory = AggregationFactory("BOTTOM_BY", 3);
+
+SELECT
+ AGGREGATE_BY(AsTuple(value, LENGTH(value)), $top_by_factory),
+ AGGREGATE_BY(AsTuple(value, key), $bottom_by_factory)
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/topfreq_mode.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/topfreq_mode.md
new file mode 100644
index 00000000000..d102cf292a0
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/aggregation/topfreq_mode.md
@@ -0,0 +1,21 @@
+## TOPFREQ и MODE {#topfreq-mode}
+
+Получение приближенного списка самых часто встречающихся значений колонки с оценкой их числа. Возвращают список структур с двумя полями:
+
+* `Value`— найденное часто встречающееся значение;
+* `Frequency` — оценка числа упоминаний в таблице.
+
+Обязательный аргумент: само значение.
+
+Опциональные аргументы:
+
+1. Для `TOPFREQ` — желаемое число элементов в результате. `MODE` является алиасом к `TOPFREQ` с 1 в этом аргументе. У `TOPFREQ` по умолчанию тоже 1.
+2. Число элементов в используемом буфере, что позволяет разменивать потребление памяти на точность. По умолчанию 100.
+
+**Примеры**
+``` yql
+SELECT
+ MODE(my_column),
+ TOPFREQ(my_column, 5, 1000)
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/abs.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/abs.md
new file mode 100644
index 00000000000..1bbf5ee22d2
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/abs.md
@@ -0,0 +1,8 @@
+## Abs {#abs}
+
+Абсолютное значение числа.
+
+**Примеры**
+``` yql
+SELECT Abs(-123); -- 123
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/aggr_factory.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/aggr_factory.md
new file mode 100644
index 00000000000..3b7de2eceae
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/aggr_factory.md
@@ -0,0 +1,73 @@
+## AggregationFactory {#aggregationfactory}
+
+Создать фабрику для [агрегационных функций](../../aggregation.md) для того чтобы разделить процесс описания того, как агрегировать данные, и то, к каким данным это применять.
+
+Аргументы:
+
+1. Строка в кавычках, являющаяся именем агрегационной функции, например ["MIN"](../../aggregation.md#min).
+2. Опциональные параметры агрегационной функции, которые не зависят от данных. Например, значение percentile в [PERCENTILE](../../aggregation.md#percentile).
+
+Полученную фабрику можно использовать как второй параметр функции [AGGREGATE_BY](../../aggregation.md#aggregateby).
+Если агрегационная функция работает на двух колонках вместо одной, как например, [MIN_BY](../../aggregation.md#minby), то в [AGGREGATE_BY](../../aggregation.md#aggregateby) первым аргументом передается `Tuple` из двух значений. Подробнее это указано при описании такой агрегационной функции.
+
+**Примеры:**
+``` yql
+$factory = AggregationFactory("MIN");
+SELECT
+ AGGREGATE_BY(value, $factory) AS min_value -- применить MIN агрегацию к колонке value
+FROM my_table;
+```
+
+## AggregateTransform... {#aggregatetransform}
+
+`AggregateTransformInput()` преобразует фабрику для [агрегационных функций](../../aggregation.md), например, полученную через функцию [AggregationFactory](#aggregationfactory) в другую фабрику, в которой перед началом выполнения агрегации производится указанное преобразование входных элементов.
+
+Аргументы:
+
+1. Фабрика для агрегационных функций;
+2. Лямбда функция с одним аргументом, преобразующая входной элемент.
+
+**Примеры:**
+``` yql
+$f = AggregationFactory("sum");
+$g = AggregateTransformInput($f, ($x) -> (cast($x as Int32)));
+$h = AggregateTransformInput($f, ($x) -> ($x * 2));
+select ListAggregate([1,2,3], $f); -- 6
+select ListAggregate(["1","2","3"], $g); -- 6
+select ListAggregate([1,2,3], $h); -- 12
+```
+
+`AggregateTransformOutput()` преобразует фабрику для [агрегационных функций](../../aggregation.md), например, полученную через функцию [AggregationFactory](#aggregationfactory) в другую фабрику, в которой после окончания выполнения агрегации производится указанное преобразование результата.
+
+Аргументы:
+
+1. Фабрика для агрегационных функций;
+2. Лямбда функция с одним аргументом, преобразующая результат.
+
+**Примеры:**
+``` yql
+$f = AggregationFactory("sum");
+$g = AggregateTransformOutput($f, ($x) -> ($x * 2));
+select ListAggregate([1,2,3], $f); -- 6
+select ListAggregate([1,2,3], $g); -- 12
+```
+
+## AggregateFlatten {#aggregateflatten}
+
+Адаптирует фабрику для [агрегационных функций](../../aggregation.md), например, полученную через функцию [AggregationFactory](#aggregationfactory) так, чтобы выполнять агрегацию над входными элементами - списками. Эта операция похожа на [FLATTEN LIST BY](../../../syntax/flatten.md) - производится агрегация каждого элемента списка.
+
+Аргументы:
+
+1. Фабрика для агрегационных функций.
+
+**Примеры:**
+``` yql
+$i = AggregationFactory("AGGREGATE_LIST_DISTINCT");
+$j = AggregateFlatten($i);
+select AggregateBy(x, $j) from (
+ select [1,2] as x
+ union all
+ select [2,3] as x
+); -- [1, 2, 3]
+
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/as_container.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/as_container.md
new file mode 100644
index 00000000000..b5904a676ab
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/as_container.md
@@ -0,0 +1,36 @@
+## AsTuple, AsStruct, AsList, AsDict, AsSet, AsListStrict, AsDictStrict и AsSetStrict {#as-container}
+
+Создает контейнеры соответствующих типов. Также доступна [операторная запись](#containerliteral) литералов контейнеров.
+
+Особенности:
+
+* Элементы контейнеров передаются через аргументы, таким образом число элементов результирующего контейнера равно числу переданных аргументов, кроме случая, когда повторяются ключи словаря.
+* В `AsTuple` и `AsStruct` могут быть вызваны без аргументов, а также аргументы могут иметь разные типы.
+* Имена полей в `AsStruct` задаются через `AsStruct(field_value AS field_name)`.
+* Для создания списка требуется хотя бы один аргумент, если нужно вывести типы элементов. Для создания пустого списка с заданным типом элементов используется функция [ListCreate](../../list.md#listcreate). Можно создать пустой список как вызов `AsList()` без аргументов, в этом случае это выражение будет иметь тип `EmptyList`.
+* Для создания словаря требуется хотя бы один аргумент, если нужно вывести типы элементов. Для создания пустого словаря с заданным типом элементов используется функция [DictCreate](../../dict.md#dictcreate). Можно создать пустой словарь как вызов `AsDict()` без аргументов, в этом случае это выражение будет иметь тип `EmptyDict`.
+* Для создания множества требуется хотя бы один аргумент, если нужно вывести типы элементов. Для создания пустого множества с заданным типом элементов используется функция [SetCreate](../../dict.md#setcreate). Можно создать пустое множество как вызов `AsSet()` без аргументов, в этом случае это выражение будет иметь тип `EmptyDict`.
+* `AsList` выводит общий тип элементов списка. При несовместимых типах генерируется ошибка типизации.
+* `AsDict` выводит раздельно общие типы ключей и значений. При несовместимых типах генерируется ошибка типизации.
+* `AsSet` выводит общие типы ключей. При несовместимых типах генерируется ошибка типизации.
+* `AsListStrict`, `AsDictStrict`, `AsSetStrict` требуют одинакового типа для аргументов.
+* В `AsDict` и `AsDictStrict` в качестве аргументов ожидаются `Tuple` из двух элементов: ключ и значение, соответственно. Если ключи повторяются, в словаре останется только значение для первого ключа.
+* В `AsSet` и `AsSetStrict` в качестве аргументов ожидаются ключи.
+
+**Примеры**
+``` yql
+SELECT
+ AsTuple(1, 2, "3") AS `tuple`,
+ AsStruct(
+ 1 AS a,
+ 2 AS b,
+ "3" AS c
+ ) AS `struct`,
+ AsList(1, 2, 3) AS `list`,
+ AsDict(
+ AsTuple("a", 1),
+ AsTuple("b", 2),
+ AsTuple("c", 3)
+ ) AS `dict`,
+ AsSet(1, 2, 3) AS `set`
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/as_tagged.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/as_tagged.md
new file mode 100644
index 00000000000..efda31d71e1
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/as_tagged.md
@@ -0,0 +1,16 @@
+## AsTagged, Untag {#as-tagged}
+
+Оборачивает значение в [Tagged тип данных](../../../types/special.md) с указанной меткой с сохранением физического типа данных. `Untag` — обратная операция.
+
+Обязательные аргументы:
+
+1. Значение произвольного типа;
+2. Имя метки.
+
+Возвращает копию значения из первого аргумента с указанной меткой в типе данных.
+
+Примеры сценариев использования:
+
+* Возвращение на клиент для отображения в веб-интерфейсе медиа-файлов из base64-encoded строк{% if feature_webui %}. Поддержка меток в веб-UI YQL [описана здесь](../../../interfaces/web_tagged.md){% endif %}.
+{% if feature_mapreduce %}* Защита на границах вызова UDF от передачи некорректных значений;{% endif %}
+* Дополнительные уточнения на уровне типов возвращаемых колонок.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/bitops.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/bitops.md
new file mode 100644
index 00000000000..2fee0f0fa78
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/bitops.md
@@ -0,0 +1,17 @@
+## ...Bit {#bitops}
+
+`TestBit()`, `ClearBit()`, `SetBit()` и `FlipBit()` - проверить, сбросить, установить или инвертировать бит в беззнаковом числе по указанному порядковому номеру бита.
+
+Аргументы:
+
+1. Беззнаковое число, над которым выполнять требуемую операцию. TestBit также реализован и для строк.
+2. Номер бита.
+
+TestBit возвращает `true/false`. Остальные функции возвращают копию своего первого аргумента с проведенным соответствующим преобразованием.
+
+**Примеры:**
+``` yql
+SELECT
+ TestBit(1u, 0), -- true
+ SetBit(8u, 0); -- 9
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/byteat.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/byteat.md
new file mode 100644
index 00000000000..604b6d7e50f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/byteat.md
@@ -0,0 +1,16 @@
+## ByteAt {#byteat}
+
+Получение значение байта в строке по индексу от её начала. В случае некорректного индекса возвращается `NULL`.
+
+Аргументы:
+
+1. Строка: `String` или `Utf8`;
+2. Индекс: `Uint32`.
+
+**Примеры**
+``` yql
+SELECT
+ ByteAt("foo", 0), -- 102
+ ByteAt("foo", 1), -- 111
+ ByteAt("foo", 9); -- NULL
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/callable.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/callable.md
new file mode 100644
index 00000000000..ef89712b940
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/callable.md
@@ -0,0 +1,22 @@
+## Callable {#callable}
+
+Создать вызываемое значение с заданной сигнатурой из лямбда-функции. Обычно используется для того, чтобы размещать вызываемые значения в контейнерах.
+
+Аргументы:
+
+1. Тип;
+2. Лямбда-функция.
+
+**Примеры:**
+``` yql
+$lambda = ($x) -> {
+ RETURN CAST($x as String)
+};
+
+$callables = AsTuple(
+ Callable(Callable<(Int32)->String>, $lambda),
+ Callable(Callable<(Bool)->String>, $lambda),
+);
+
+SELECT $callables.0(10), $callables.1(true);
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/coalesce.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/coalesce.md
new file mode 100644
index 00000000000..922a0b65c58
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/coalesce.md
@@ -0,0 +1,30 @@
+## COALESCE {#coalesce}
+
+Перебирает аргументы слева направо и возвращает первый найденный непустой аргумент. Чтобы результат получился гарантированно непустым (не [optional типа](../../../types/optional.md)), самый правый аргумент должен быть такого типа (зачастую используют литерал). При одном аргументе возвращает его без изменений.
+
+Позволяет передавать потенциально пустые значения в функции, которые не умеют обрабатывать их самостоятельно.
+
+Доступен краткий формат записи в виде оператора `??`, обладающего низким приоритетом (ниже булевых операций). Можно использовать алиас `NVL`.
+
+**Примеры**
+``` yql
+SELECT COALESCE(
+ maybe_empty_column,
+ "it's empty!"
+) FROM my_table;
+```
+
+``` yql
+SELECT
+ maybe_empty_column ?? "it's empty!"
+FROM my_table;
+```
+
+``` yql
+SELECT NVL(
+ maybe_empty_column,
+ "it's empty!"
+) FROM my_table;
+```
+
+<span style="color: gray;">(все три примера выше эквивалентны)</span> \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/container_literal.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/container_literal.md
new file mode 100644
index 00000000000..e35b515c901
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/container_literal.md
@@ -0,0 +1,34 @@
+## Литералы контейнеров {#containerliteral}
+
+Для некоторых контейнеров возможна операторная форма записи их литеральных значений:
+
+* Кортеж — `(value1, value2...)`;
+* Структура — `<|name1: value1, name2: value2...|>`;
+* Список — `[value1, value2,...]`;
+* Словарь — `{key1: value1, key2: value2...}`;
+* Множество — `{key1, key2...}`.
+
+Во всех случаях допускается незначащая хвостовая запятая. Для кортежа с одним элементом эта запятая является обязательной - ```(value1,)```.
+Для имен полей в литерале структуры допускается использовать выражение, которое можно посчитать в evaluation time, например, строковые литералы, а также идентификаторы (в том числе в backticks).
+
+Для списка внутри используется функция [AsList](#aslist), словаря - [AsDict](#asdict), множества - [AsSet](#asset), кортежа - [AsTuple](#astuple), структуры - [AsStruct](#asstruct).
+
+**Примеры**
+``` yql
+$name = "computed " || "member name";
+SELECT
+ (1, 2, "3") AS `tuple`,
+ <|
+ `complex member name`: 2.3,
+ b: 2,
+ $name: "3",
+ "inline " || "computed member name": false
+ |> AS `struct`,
+ [1, 2, 3] AS `list`,
+ {
+ "a": 1,
+ "b": 2,
+ "c": 3,
+ } AS `dict`,
+ {1, 2, 3} AS `set`
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/current_tz.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/current_tz.md
new file mode 100644
index 00000000000..3dd31df9202
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/current_tz.md
@@ -0,0 +1,44 @@
+## CurrentTz... {#current-tz}
+
+`CurrentTzDate()`, `CurrentTzDatetime()` и `CurrentTzTimestamp()` - получение текущей даты и/или времени в указанной в первом аргументе [IANA временной зоне](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). Тип данных результата указан в конце названия функции.
+
+Последующие аргументы опциональны и работают по тому же принципу, что и у [RANDOM](#random).
+
+**Примеры**
+``` yql
+SELECT CurrentTzDate("Europe/Moscow");
+```
+``` yql
+SELECT CurrentTzTimestamp("Europe/Moscow", TableRow()) FROM my_table;
+```
+
+## AddTimezone
+
+Добавление информации о временной зоне к дате/времени, заданных в UTC. При выводе в результате `SELECT` или после `CAST` в `String` будут применены правила временной зоны по вычислению смещения времени.
+
+Аргументы:
+
+1. Дата - тип `Date`/`Datetime`/`Timestamp`;
+2. [IANA имя временной зоны](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
+
+Тип результата - `TzDate`/`TzDatetime`/`TzTimestamp`, в зависимости от типа данных входа.
+
+**Примеры**
+``` yql
+SELECT AddTimezone(Datetime("2018-02-01T12:00:00Z"), "Europe/Moscow");
+```
+
+## RemoveTimezone
+
+Удаление информации о временной зоне и перевод в дату/время, заданные в UTC.
+
+Аргументы:
+
+1. Дата - тип `TzDate`/`TzDatetime`/`TzTimestamp`.
+
+Тип результата - `Date`/`Datetime`/`Timestamp`, в зависимости от типа данных входа.
+
+**Примеры**
+``` yql
+SELECT RemoveTimezone(TzDatetime("2018-02-01T12:00:00,Europe/Moscow"));
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/current_utc.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/current_utc.md
new file mode 100644
index 00000000000..6f989ea8e03
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/current_utc.md
@@ -0,0 +1,13 @@
+## CurrentUtc... {#current-utc}
+
+`CurrentUtcDate()`, `CurrentUtcDatetime()` и `CurrentUtcTimestamp()` - получение текущей даты и/или времени в UTC. Тип данных результата указан в конце названия функции.
+
+Аргументы опциональны и работают по тому же принципу, что и у [RANDOM](#random).
+
+**Примеры**
+``` yql
+SELECT CurrentUtcDate();
+```
+``` yql
+SELECT CurrentUtcTimestamp(TableRow()) FROM my_table;
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/data-type-literals.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/data-type-literals.md
new file mode 100644
index 00000000000..5e4ff03e594
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/data-type-literals.md
@@ -0,0 +1,49 @@
+## Литералы простых типов {#data-type-literals}
+
+Для простых типов могут быть созданы литералы на основании строковых литералов.
+
+**Синтаксис**
+
+<Простой тип>(<строка>[, <дополнительные атрибуты>])
+
+В отличие от `CAST("myString" AS MyType)`:
+
+* Проверка на приводимость литерала к требуемому типу происходит на этапе валидации;
+* Результат не является optional.
+
+Для типов данных `Date`, `Datetime`, `Timestamp` и `Interval` поддерживаются литералы только в формате, соответствующем [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). У `Interval` есть следующие отличия от стандарта:
+
+* поддерживается отрицательный знак для сдвигов в прошлое;
+* микросекунды могут быть записаны как дробная часть секунд;
+* единицы измерения больше недель не доступны;
+* не поддерживаются варианты с началом/концом интервала, а также повторами.
+
+Для типов данных `TzDate`, `TzDatetime`, `TzTimestamp` литералы также задаются в формате, соответствующем [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601), но вместо опционального суффикса Z через запятую указывается [IANA имя временной зоны](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones), например, GMT или Europe/Moscow.
+
+{% include [decimal args](../../../_includes/decimal_args.md) %}
+
+**Примеры**
+``` yql
+SELECT
+ Bool("true"),
+ Uint8("0"),
+ Int32("-1"),
+ Uint32("2"),
+ Int64("-3"),
+ Uint64("4"),
+ Float("-5"),
+ Double("6"),
+ Decimal("1.23", 5, 2), -- до 5 десятичных знаков, из которых 2 после запятой
+ String("foo"),
+ Utf8("привет"),
+ Yson("<a=1>[3;%false]"),
+ Json(@@{"a":1,"b":null}@@),
+ Date("2017-11-27"),
+ Datetime("2017-11-27T13:24:00Z"),
+ Timestamp("2017-11-27T13:24:00.123456Z"),
+ Interval("P1DT2H3M4.567890S"),
+ TzDate("2017-11-27,Europe/Moscow"),
+ TzDatetime("2017-11-27T13:24:00,America/Los_Angeles"),
+ TzTimestamp("2017-11-27T13:24:00.123456,GMT"),
+ Uuid("f9d5cc3f-f1dc-4d9c-b97e-766e57ca4ccb");
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/ensure.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/ensure.md
new file mode 100644
index 00000000000..978b8ccf68a
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/ensure.md
@@ -0,0 +1,42 @@
+## Ensure... {#ensure}
+
+Проверка пользовательских условий:
+
+* `Ensure()` — проверка верности предиката во время выполнения запроса.
+* `EnsureType()` — проверка точного соответствия типа выражения указанному.
+* `EnsureConvertibleTo()` — мягкая проверка соответствия типа выражения, работающая по тем же правилам, что и неявное приведение типов.
+
+Если проверка не прошла успешно, то весь запрос завершается с ошибкой.
+
+Аргументы:
+
+1. Выражение, которое станет результатом вызова функции в случае успеха проверки. Оно же подвергается проверке на тип данных в соответствующих функциях.
+2. В Ensure — булевый предикат, который проверяется на `true`. В остальных функциях — тип данных, который может быть получен через [предназначенные для этого функции](../../types.md), либо строковый литерал с [текстовым описанием типа](../../../types/type_string.md).
+3. Опциональная строка с комментарием к ошибке, которая попадет в общее сообщение об ошибке при завершении запроса. Для проверок типов не может использовать сами данные, так как они выполняются на этапе валидации запроса, а для Ensure — может быть произвольным выражением.
+
+Для проверки условий по финальному результату вычисления Ensure удобно использовать в сочетании с [DISCARD SELECT](../../../syntax/discard.md).
+
+**Примеры**
+``` yql
+SELECT Ensure(
+ value,
+ value < 100,
+ "value out or range"
+) AS value FROM my_table;
+```
+
+``` yql
+SELECT EnsureType(
+ value,
+ TypeOf(other_value),
+ "expected value and other_value to be of same type"
+) AS value FROM my_table;
+```
+
+``` yql
+SELECT EnsureConvertibleTo(
+ value,
+ Double?,
+ "expected value to be numeric"
+) AS value FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/enum.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/enum.md
new file mode 100644
index 00000000000..21b492db0ff
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/enum.md
@@ -0,0 +1,28 @@
+## Enum, AsEnum {#enum}
+
+`Enum()` cоздает значение перечисления.
+
+Аргументы:
+
+* Строка с именем поля
+* Тип перечисления
+
+**Пример**
+``` yql
+$enum_type = Enum<Foo, Bar>;
+SELECT
+ Enum("Foo", $enum_type) as Enum1Value,
+ Enum("Bar", $enum_type) as Enum2Value;
+```
+
+`AsEnum()` создает значение [перечисления](../../../types/containers.md) с одним элементом. Это значение может быть неявно преобразовано к любому перечислению, содержащему такое имя.
+
+Аргументы:
+
+* Строка с именем элемента перечисления
+
+**Пример**
+``` yql
+SELECT
+ AsEnum("Foo");
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/evaluate_expr_atom.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/evaluate_expr_atom.md
new file mode 100644
index 00000000000..ccd8c2ddff2
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/evaluate_expr_atom.md
@@ -0,0 +1,26 @@
+## EvaluateExpr, EvaluateAtom {#evaluate_expr_atom}
+
+Возможность выполнить выражение до начала основного расчета и подставить его результат в запрос как литерал (константу). Во многих контекстах, где в стандартном SQL ожидалась бы только константа (например, в именах таблиц, количестве строк в [LIMIT](../../../syntax/select.md#limit) и т.п.) этот функционал активируется неявным образом автоматически.
+
+EvaluateExpr может использоваться в тех местах, где грамматикой уже ожидается выражение. Например, с его помощью можно:
+
+* округлить текущее время до дней, недель или месяцев и подставить в запрос, что затем позволит корректно работать [кешированию запросов](../../../syntax/pragma.md#yt.querycachemode), хотя обычно использование [функций для получения текущего времени](#currentutcdate) его полностью отключает;
+* сделать тяжелое вычисление с небольшим результатом один раз на запрос вместо одного раза на каждую джобу.
+
+EvaluateAtom позволяет динамически создать [атом](../../../types/special.md), но т.к. ими в основном оперирует более низкий уровень [s-expressions](/docs/s_expressions/functions), то использовать эту функцию напрямую как правило не рекомендуется.
+
+Единственный аргумент у обоих функций — само выражение для вычисления и подстановки.
+
+Ограничения:
+
+* выражение не должно приводить к запуску MapReduce операций;
+* данный функционал полностью заблокирован в YQL over YDB.
+
+**Примеры:**
+``` yql
+$now = CurrentUtcDate();
+SELECT EvaluateExpr(
+ DateTime::MakeDate(DateTime::StartOfWeek($now)
+ )
+);
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/files.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/files.md
new file mode 100644
index 00000000000..49b6eb3c878
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/files.md
@@ -0,0 +1,56 @@
+## FileContent и FilePath {#file-content-path}
+
+Как [консольный](../../../interfaces/cli.md), так и [веб](../../../interfaces/web.md)-интерфейсы позволяют «прикладывать» к запросу произвольные именованные файлы. С помощью этих функций можно по имени приложенного файла получить его содержимое или путь в «песочнице» и в дальнейшем использовать в запросе произвольным образом.
+
+Аргумент `FileContent` и `FilePath` — строка с алиасом.
+
+**Примеры**
+``` yql
+SELECT "Content of "
+ || FilePath("my_file.txt")
+ || ":\n"
+ || FileContent("my_file.txt");
+```
+## FolderPath {#folderpath}
+
+Получение пути до корня директории с несколькими «приложенными» файлами с указанным общим префиксом.
+
+Аргумент — строка с префиксом среди алиасов.
+
+Также см. [PRAGMA File](../../../syntax/pragma.md#file) и [PRAGMA Folder](../../../syntax/pragma.md#folder).
+
+**Примеры**
+``` yql
+PRAGMA File("foo/1.txt", "http://url/to/somewhere");
+PRAGMA File("foo/2.txt", "http://url/to/somewhere/else");
+PRAGMA File("bar/3.txt", "http://url/to/some/other/place");
+
+SELECT FolderPath("foo"); -- в директории по возвращённому пути будут
+ -- находиться файлы 1.txt и 2.txt, скачанные по указанным выше ссылкам
+```
+
+## ParseFile
+
+Получить из приложенного текстового файла список значений. Может использоваться в сочетании с [IN](../../../syntax/expressions.md#in) и прикладыванием файла по URL <span style="color:gray;">(инструкции по прикладыванию файлов для {% if feature_webui %}[веб-интерфейса](../../../interfaces/web.md#attach) и {% endif %} [клиента](../../../interfaces/cli.md#attach))</span>.
+
+Поддерживается только один формат файла — по одному значению на строку.{% if feature_udf_noncpp %} Для чего-то более сложного прямо сейчас придется написать небольшую UDF на [Python](../../../udf/python.md) или [JavaScript](../../../udf/javascript.md). {% endif %}
+
+Два обязательных аргумента:
+
+1. Тип ячейки списка: поддерживаются только строки и числовые типы;
+2. Имя приложенного файла.
+
+{% note info "Примечание" %}
+
+Возвращаемое значение - ленивый список. Для многократного использования его нужно обернуть в функцию [ListCollect](../../list.md#listcollect)
+
+{% endnote %}
+
+**Примеры:**
+``` yql
+SELECT ListLength(ParseFile("String", "my_file.txt"));
+```
+``` yql
+SELECT * FROM my_table
+WHERE int_column IN ParseFile("Int64", "my_file.txt"));
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/find.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/find.md
new file mode 100644
index 00000000000..aa97767ead7
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/find.md
@@ -0,0 +1,51 @@
+## FIND {#find}
+
+Поиск позиции подстроки в строке.
+
+Обязательные аргументы:
+
+* Исходная строка;
+* Искомая подстрока.
+
+Опциональные аргументы:
+
+* Позиция — в байтах, с которой начинать поиск (целое число, или `NULL` по умолчанию, означающий «от начала исходной строки»).
+
+Возвращает первую найденную позицию подстроки, или `NULL`, означающий что искомая подстрока с указанной позиции не найдена.
+
+**Примеры**
+``` yql
+SELECT FIND("abcdefg_abcdefg", "abc"); -- 0
+```
+``` yql
+SELECT FIND("abcdefg_abcdefg", "abc", 1); -- 8
+```
+``` yql
+SELECT FIND("abcdefg_abcdefg", "abc", 9); -- null
+```
+
+## RFIND {#rfind}
+
+Обратный поиск позиции подстроки в строке, от конца к началу.
+
+Обязательные аргументы:
+
+* Исходная строка;
+* Искомая подстрока.
+
+Опциональные аргументы:
+
+* Позиция — в байтах, с которой начинать поиск (целое число, или `NULL` по умолчанию, означающий «от конца исходной строки»).
+
+Возвращает первую найденную позицию подстроки, или `NULL`, означающий, что искомая подстрока с указанной позиции не найдена.
+
+**Примеры**
+``` yql
+SELECT RFIND("abcdefg_abcdefg", "bcd"); -- 9
+```
+``` yql
+SELECT RFIND("abcdefg_abcdefg", "bcd", 8); -- 1
+```
+``` yql
+SELECT RFIND("abcdefg_abcdefg", "bcd", 0); -- null
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/if.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/if.md
new file mode 100644
index 00000000000..747eeea0989
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/if.md
@@ -0,0 +1,15 @@
+## IF {#if}
+
+Проверяет условие `IF(condition_expression, then_expression, else_expression)`.
+
+Является упрощенной альтернативой для [CASE WHEN ... THEN ... ELSE ... END](../../../syntax/expressions.md#case).
+
+Аргумент `else_expression` можно не указывать. В этом случае, если условие ложно (`condition_expression` вернул `false`), будет возвращено пустое значение с типом, соответствующим `then_expression` и допускающим значение `NULL`. Таким образом, у результата получится [optional тип данных](../../../types/optional.md).
+
+**Примеры**
+``` yql
+SELECT
+ IF(foo > 0, bar, baz) AS bar_or_baz,
+ IF(foo > 0, foo) AS only_positive_foo
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/intro.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/intro.md
new file mode 100644
index 00000000000..8a55343d145
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/intro.md
@@ -0,0 +1,3 @@
+# Базовые встроенные функции
+
+Ниже описаны функции общего назначения, а для специализированных функций есть отдельные статьи: [агрегатные](../../aggregation.md){% if feature_window_functions %}, [оконные](../../window.md){% endif %}, а также для работы со [списками](../../list.md), [словарями](../../dict.md), [структурами](../../struct.md), [типами данных](../../types.md){% if feature_codegen %} и [генерацией кода](../../codegen.md){% endif %}.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/length.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/length.md
new file mode 100644
index 00000000000..a343e35a63c
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/length.md
@@ -0,0 +1,17 @@
+## LENGTH {#length}
+
+Возвращает длину строки в байтах. Также эта функция доступна под именем `LEN`.
+
+**Примеры**
+``` yql
+SELECT LENGTH("foo");
+```
+``` yql
+SELECT LEN("bar");
+```
+
+{% note info %}
+
+Для вычисления длины строки в unicode символах можно воспользоваться функцией [Unicode::GetLength](../../../udf/list/unicode.md).<br><br>Для получения числа элементов в списке нужно использовать функцию [ListLength](../../list.md#listlength).
+
+{% endnote %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/max_min.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/max_min.md
new file mode 100644
index 00000000000..243c9d08772
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/max_min.md
@@ -0,0 +1,12 @@
+## MAX_OF, MIN_OF, GREATEST и LEAST {#max-min}
+
+Возвращает минимальный или максимальный среди N аргументов. Эти функции позволяют не использовать стандартную для SQL конструкцию `CASE WHEN a < b THEN a ELSE b END`, которая была бы особенно громоздкой для N больше двух.
+
+Типы аргументов должны быть приводимы друг к другу и могут допускать значение `NULL`.
+
+`GREATEST` является синонимом к `MAX_OF`, а `LEAST` — к `MIN_OF`.
+
+**Примеры**
+``` yql
+SELECT MIN_OF(1, 2, 3);
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/metadata.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/metadata.md
new file mode 100644
index 00000000000..330501157a7
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/metadata.md
@@ -0,0 +1,19 @@
+## Доступ к метаданным текущей операции {#metadata}
+
+При запуске YQL операций через веб-интерфейс или HTTP API, предоставляется доступ к следующей информации:
+
+* `CurrentOperationId()` — приватный идентификатор операции;
+* `CurrentOperationSharedId()` — публичный идентификатор операции;
+* `CurrentAuthenticatedUser()` — логин текущего пользователя.
+
+Аргументов нет.
+
+При отсутствии данной информации, например, при запуске в embedded режиме, возвращают пустую строку.
+
+**Примеры**
+``` yql
+SELECT
+ CurrentOperationId(),
+ CurrentOperationSharedId(),
+ CurrentAuthenticatedUser();
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/nanvl.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/nanvl.md
new file mode 100644
index 00000000000..19715ae1f44
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/nanvl.md
@@ -0,0 +1,17 @@
+## NANVL {#nanvl}
+
+Заменяет значения `NaN` (not a number) в выражениях типа `Float`, `Double` или [Optional](../../../types/optional.md).
+
+Аргументы:
+
+1. Выражение, в котором нужно произвести замену.
+2. Значение, на которое нужно заменить `NaN`.
+
+Если один из агрументов `Double`, то в выдаче `Double`, иначе `Float`. Если один из агрументов `Optional`, то и в выдаче `Optional`.
+
+**Примеры**
+``` yql
+SELECT
+ NANVL(double_column, 0.0)
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/optional_ops.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/optional_ops.md
new file mode 100644
index 00000000000..2fa6d178653
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/optional_ops.md
@@ -0,0 +1,39 @@
+## Just, Unwrap, Nothing {#optional-ops}
+
+`Just()` - Изменить тип данных значения на [optional](../../../types/optional.md) от текущего типа данных (то есть `T` превращается в `T?`).
+
+Обратная операция — [Unwrap](#unwrap).
+
+**Примеры**
+``` yql
+SELECT
+ Just("my_string"); -- String?
+```
+
+`Unwrap()` - Преобразование значения [optional](../../../types/optional.md) типа данных в соответствующий не-optional тип с ошибкой времени выполнений, если в данных оказался `NULL`. Таким образом, `T?` превращается в `T`.
+
+Если значение не является [optional](../../../types/optional.md), то функция возвращает свой первый аргумент без изменений.
+
+Аргументы:
+
+1. Значение для преобразования;
+2. Опциональная строка с комментарием для текста ошибки.
+
+Обратная операция — [Just](#just).
+
+**Примеры**
+``` yql
+$value = Just("value");
+
+SELECT Unwrap($value, "Unexpected NULL for $value");
+```
+
+`Nothing()` - Создать пустое значение указанного [Optional](../../../types/optional.md) типа данных.
+
+**Примеры**
+``` yql
+SELECT
+ Nothing(String?); -- пустое значение (NULL) с типом String?
+```
+
+[Подробнее о ParseType и других функциях для работы с типами данных](../../types.md). \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/pickle.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/pickle.md
new file mode 100644
index 00000000000..03e3d08f742
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/pickle.md
@@ -0,0 +1,17 @@
+## Pickle, Unpickle {#pickle}
+
+`Pickle()` и `StablePickle()` сериализуют произвольный объект в последовательность байт, если это возможно. Типовыми несериализуемыми объектами являются Callable и Resource. Формат сериализации не версионируется, допускается использовать в пределах одного запроса. Для типа Dict функция StablePickle предварительно сортирует ключи, а для Pickle порядок элементов словаря в сериализованном представлении не определен.
+
+`Unpickle()` — обратная операция (десериализация), где первым аргументом передается тип данных результата, а вторым — строка с результатом `Pickle()` или `StablePickle()`.
+
+Примеры:
+``` yql
+SELECT *
+FROM my_table
+WHERE Digest::MurMurHash32(
+ Pickle(TableRow())
+ ) % 10 == 0; -- в реальности лучше использовать TABLESAMPLE
+
+$buf = Pickle(123);
+SELECT Unpickle(Int32, $buf);
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/random.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/random.md
new file mode 100644
index 00000000000..62d4b2aa127
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/random.md
@@ -0,0 +1,55 @@
+## Random... {#random}
+
+Генерирует псевдослучайное число:
+
+* `Random()` — число с плавающей точкой (Double) от 0 до 1;
+* `RandomNumber()` — целое число из всего диапазона Uint64;
+* `RandomUuid()` — [Uuid version 4](https://tools.ietf.org/html/rfc4122#section-4.4).
+
+При генерации случайных чисел аргументы не используются и нужны исключительно для управления моментом вызова. В каждый момент вызова возвращается новое случайное число. Поэтому:
+
+* Повторный вызов Random в рамках **одного запроса** при идентичном наборе аргументов возвращает тот же самый набор случайных чисел. Важно понимать, что речь именно про сами аргументы (текст между круглыми скобками), а не их значения.
+* Вызовы Random с одним и тем же набором аргументов в **разных запросах** вернут разные наборы случайных чисел.
+
+{% note warning %}
+
+Если Random используется в [именованных выражениях](../../../syntax/expressions.md#named-nodes), то его однократное вычисление не гарантируется. В зависимости от оптимизаторов и среды исполнения он может посчитаться как один раз, так и многократно. Для гарантированного однократного подсчета необходимо в этом случае материализовать именованное выражение в таблицу.
+
+{% endnote %}
+
+Сценарии использования:
+
+* `SELECT RANDOM(1);` — получить одно случайное значение на весь запрос и несколько раз его использовать (чтобы получить несколько, можно передать разные константы любого типа);
+* `SELECT RANDOM(1) FROM table;` — одно и то же случайное число на каждую строку таблицы;
+* `SELECT RANDOM(1), RANDOM(2) FROM table;` — по два случайных числа на каждую строку таблицы, все числа в каждой из колонок одинаковые;
+* `SELECT RANDOM(some_column) FROM table;` — разные случайные числа на каждую строку таблицы;
+* `SELECT RANDOM(some_column), RANDOM(some_column) FROM table;` — разные случайные числа на каждую строку таблицы, но в рамках одной строки — два одинаковых числа;
+* `SELECT RANDOM(some_column), RANDOM(some_column + 1) FROM table;` или `SELECT RANDOM(some_column), RANDOM(other_column) FROM table;` — две колонки, и все с разными числами.
+
+**Примеры**
+``` yql
+SELECT
+ Random(key) -- [0, 1)
+FROM my_table;
+```
+
+``` yql
+SELECT
+ RandomNumber(key) -- [0, Max<Uint64>)
+FROM my_table;
+```
+
+``` yql
+SELECT
+ RandomUuid(key) -- Uuid version 4
+FROM my_table;
+```
+
+``` yql
+SELECT
+ RANDOM(column) AS rand1,
+ RANDOM(column) AS rand2, -- same as rand1
+ RANDOM(column, 1) AS randAnd1, -- different from rand1/2
+ RANDOM(column, 2) AS randAnd2 -- different from randAnd1
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/s_expressions.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/s_expressions.md
new file mode 100644
index 00000000000..5c80ef837bf
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/s_expressions.md
@@ -0,0 +1,5 @@
+## YQL::, s-expressions {#s-expressions}
+
+Полный список внутренних функций YQL находится в [документации к s-expressions](/docs/s_expressions/functions), альтернативному низкоуровневому синтаксису YQL. Любую из перечисленных там функций можно вызвать и из SQL синтаксиса, добавив к её имени префикс `YQL::`, но это не рекомендуется делать, т.к. данный механизм предназначен в первую очередь для временного обхода возможных проблем, а также для нужд внутреннего тестирования.
+
+Если функция доступна в SQL синтаксисе без префикса `YQL::`, то её поведение имеет право отличаться от одноименной функции из документации по s-expressions, если таковая существует.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/starts_ends_with.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/starts_ends_with.md
new file mode 100644
index 00000000000..932d95024f5
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/starts_ends_with.md
@@ -0,0 +1,24 @@
+## StartsWith, EndsWith {#starts_ends_with}
+
+Проверка наличия префикса или суффикса в строке.
+
+Обязательные аргументы:
+
+* Исходная строка;
+* Искомая подстрока.
+
+Аргументы могут быть типов `String` или `Utf8` и могут быть опциональными.
+
+**Примеры**
+``` yql
+SELECT StartsWith("abc_efg", "abc") AND EndsWith("abc_efg", "efg"); -- true
+```
+``` yql
+SELECT StartsWith("abc_efg", "efg") OR EndsWith("abc_efg", "abc"); -- false
+```
+``` yql
+SELECT StartsWith("abcd", NULL); -- null
+```
+``` yql
+SELECT EndsWith(NULL, Utf8("")); -- null
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/staticmap.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/staticmap.md
new file mode 100644
index 00000000000..a27fe717b43
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/staticmap.md
@@ -0,0 +1,23 @@
+## StaticMap
+
+Преобразует структуру или кортеж, применяя лямбду к каждому элементу.
+
+Аргументы:
+
+* Структура или кортеж;
+* Лямбда для обработки элементов.
+
+Результат: структура или кортеж с аналогичным первому аргументу количеством и именованием элементов, а типы данных элементов определяются результатами лямбды.
+
+**Примеры:**
+``` yql
+SELECT *
+FROM (
+ SELECT
+ StaticMap(TableRow(), ($item) -> {
+ return CAST($item AS String);
+ })
+ FROM my_table
+) FLATTEN COLUMNS; -- преобразование всех колонок в строки
+```
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/staticzip.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/staticzip.md
new file mode 100644
index 00000000000..b6183d56f86
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/staticzip.md
@@ -0,0 +1,15 @@
+## StaticZip
+
+Поэлементно "склеивает" структуры или кортежи. Все аргументы (один и более) должны быть либо структурами с одинаковым набором полей, либо кортежами одинаковой длины.
+Результататом будет соответственно структура или кортеж.
+Каждый элемент результата – кортеж с соответствующими элементами из аргументов.
+
+**Примеры:**
+``` yql
+$one = <|k1:1, k2:2.0|>;
+$two = <|k1:3.0, k2:4|>;
+
+-- поэлементное сложение двух структур
+SELECT StaticMap(StaticZip($one, $two), ($tuple)->($tuple.0 + $tuple.1)) AS sum;
+```
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/substring.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/substring.md
new file mode 100644
index 00000000000..210b9330044
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/substring.md
@@ -0,0 +1,26 @@
+## SUBSTRING {#substring}
+
+Возвращает подстроку.
+
+Обязательные аргументы:
+
+* Исходная строка;
+* Позиция — отступ от начала строки в байтах (целое число) или `NULL`, означающий «от начала».
+
+Опциональные аргументы:
+
+* Длина подстроки — количество байт, начиная с указанной позиции (целое число, или `NULL` по умолчанию, означающий «до конца исходной строки»).
+
+Индексация с нуля. Если указанные позиция и длина выходят за пределы строки, возвращает пустую строку.
+Если входная строка является опциональной, то таким же является и результат.
+
+**Примеры**
+``` yql
+SELECT SUBSTRING("abcdefg", 3, 1); -- d
+```
+``` yql
+SELECT SUBSTRING("abcdefg", 3); -- defg
+```
+``` yql
+SELECT SUBSTRING("abcdefg", NULL, 3); -- abc
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/table_path_name_recindex.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/table_path_name_recindex.md
new file mode 100644
index 00000000000..c108337ed32
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/table_path_name_recindex.md
@@ -0,0 +1,53 @@
+## TablePath {#tablepath}
+
+Доступ к текущему имени таблицы, что бывает востребовано при использовании [CONCAT](../../../syntax/select.md#concat), [RANGE](../../../syntax/select.md#range) и других подобных механизмов.
+
+Аргументов нет. Возвращает строку с полным путём, либо пустую строку и warning при использовании в неподдерживаемом контексте (например, при работе с подзапросом или диапазоном из 1000+ таблиц).
+
+{% note info "Примечание" %}
+
+Функции [TablePath](#tablepath), [TableName](#tablename) и [TableRecordIndex](#tablerecordindex) не работают для временных и анонимных таблиц (возвращают пустую строку или 0 для [TableRecordIndex](#tablerecordindex)).
+Данные функции вычисляются в момент [выполнения](../../../syntax/select.md#selectexec) проекции в `SELECT`, и к этому моменту текущая таблица уже может быть временной.
+Чтобы избежать такой ситуации, следует поместить вычисление этих функций в подзапрос, как это сделано во втором примере ниже.
+
+{% endnote %}
+
+**Примеры**
+``` yql
+SELECT TablePath() FROM CONCAT(table_a, table_b);
+```
+
+``` yql
+SELECT key, tpath_ AS path FROM (SELECT a.*, TablePath() AS tpath_ FROM RANGE(`my_folder`) AS a)
+WHERE key IN $subquery;
+```
+
+## TableName {#tablename}
+
+Получить имя таблицы из пути к таблице. Путь можно получить через функцию [TablePath](#tablepath), или в виде колонки `Path` при использовании табличной функции [FOLDER](../../../syntax/select.md#folder).
+
+Необязательные аргументы:
+
+* путь к таблице, по умолчанию используется `TablePath()` (также см. его ограничения);
+* указание системы ("yt"), по правилам которой выделяется имя таблицы. Указание системы нужно только в том случае, если с помощью [USE](../../../syntax/select.md#use) не указан текущий кластер.
+
+**Примеры**
+``` yql
+USE hahn;
+SELECT TableName() FROM CONCAT(table_a, table_b);
+```
+
+``` yql
+SELECT TableName(Path, "yt") FROM hahn.FOLDER(folder_name);
+```
+
+## TableRecordIndex {#tablerecordindex}
+
+Доступ к текущему порядковому номеру строки в исходной физической таблице, **начиная с 1** (зависит от реализации хранения).
+
+Аргументов нет. При использовании в сочетании с [CONCAT](../../../syntax/select.md#concat), [RANGE](../../../syntax/select.md#range) и другими подобными механизмами нумерация начинается заново для каждой таблицы на входе. В случае использования в некорректном контексте возвращает 0.
+
+**Пример**
+``` yql
+SELECT TableRecordIndex() FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/table_row.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/table_row.md
new file mode 100644
index 00000000000..e0979f8faf7
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/table_row.md
@@ -0,0 +1,8 @@
+## TableRow{% if feature_join %}, JoinTableRow{% endif %} {#tablerow}
+
+Получение всей строки таблицы целиком в виде структуры. Аргументов нет{% if feature_join %}. `JoinTableRow` в случае `JOIN`-ов всегда возвращает структуру с префиксами таблиц{% endif %}.
+
+**Пример**
+``` yql
+SELECT TableRow() FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/to_from_bytes.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/to_from_bytes.md
new file mode 100644
index 00000000000..a68072de3b3
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/to_from_bytes.md
@@ -0,0 +1,13 @@
+## ToBytes и FromBytes {#to-from-bytes}
+
+Конвертация [простых типов данных](../../../types/primitive.md) в строку со своим бинарным представлением и обратно. Числа представляются в [little endian](https://en.wikipedia.org/wiki/Endianness#Little-endian).
+
+**Примеры**
+``` yql
+SELECT
+ ToBytes(123), -- "\u0001\u0000\u0000\u0000"
+ FromBytes(
+ "\xd2\x02\x96\x49\x00\x00\x00\x00",
+ Uint64
+ ); -- 1234567890ul
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/variant.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/variant.md
new file mode 100644
index 00000000000..6e427d0191f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/variant.md
@@ -0,0 +1,32 @@
+## Variant, AsVariant {#variant}
+
+`Variant()` создает значение варианта над кортежем или структурой.
+
+Аргументы:
+
+* Значение
+* Строка с именем поля или индексом кортежа
+* Тип варианта
+
+**Пример**
+``` yql
+$var_type = Variant<foo: Int32, bar: Bool>;
+
+SELECT
+ Variant(6, "foo", $var_type) as Variant1Value,
+ Variant(false, "bar", $var_type) as Variant2Value;
+```
+
+`AsVariant()` создает значение [варианта над структурой](../../../types/containers.md) с одним полем. Это значение может быть неявно преобразовано к любому варианту над структурой, в которой совпадает для этого имени поля тип данных и могут быть дополнительные поля с другими именами.
+
+Аргументы:
+
+* Значение
+* Строка с именем поля
+
+**Пример**
+``` yql
+SELECT
+ AsVariant(6, "foo") as VariantValue
+```
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/weakfield.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/weakfield.md
new file mode 100644
index 00000000000..828b8086a2c
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/basic/weakfield.md
@@ -0,0 +1,15 @@
+## WeakField {#weakfield}
+
+Вытаскивает колонку таблицы из строгой схемы, если оно там есть, либо из полей `_other` и `_rest`. В случае отсутствия значения возвращается `NULL`.
+
+Синтаксис: `WeakField([<table>.]<field>, <type>[, <default_value>])`.
+
+Значение по умолчанию используется только в случае отсутствия колонки в схеме данных. Чтобы подставить значение по умолчанию в любом случае можно воспользоваться [COALESCE](#coalesce).
+
+**Примеры:**
+``` yql
+SELECT
+ WeakField(my_column, String, "no value"),
+ WeakField(my_table.other_column, Int64)
+FROM my_table;
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/codegen.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/codegen.md
new file mode 100644
index 00000000000..3331bd17c55
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/codegen.md
@@ -0,0 +1,177 @@
+# Функции для работы с генерацией кода
+
+Во время выполнения вычислений можно сгенерировать код, состоящий из узлов [S-expressions](/docs/s_expressions). Для этого используется механизм представления кода, упакованного в [ресурс](../../types/special.md). После конструирования кода можно подставить его в основную програму с помощью функции [EvaluateCode](#evaluatecode). Для отладки сконвертировать код в строку можно с помощью функции [FormatCode](#formatcode).
+
+Возможные типы узлов в S-expressions, которые можно использовать для генерации кода:
+
+* Атом - нетипизированная строка из нуля и более символов.
+* Список - последовательность из нуля и более узлов. Соответствует типу `кортеж` в SQL.
+* Вызов встроенной функции - состоит из имени, выраженного атомом, и последовательности из нуля и более узлов, которые являются аргументами этой функции.
+* Объявление лямбда функции - состоит из объявления имен аргументов и узла, который является корнем тела этой лямбда функции.
+* Аргумент лямбды функции - узел, который может использоваться только внутри тела лямбда-функции.
+* Мир - специальный узел, маркирующий операции ввода/вывода.
+
+Узлы S-expressions образуют ориентированный граф. При этом атомы - всегда листовые узлы, так как не могут содержать дочерних узлов.
+
+В текстовой записи S-expressions записываются следующим образом:
+
+* Атом - ```'"foo"```. Символ апострофа (') является признаком цитирования последующей строки, обычно заключенной в кавычки.
+* Список - ```'("foo" "bar")```. Символ апострофа (') является признаком того, что в скобках не будет вызова функции.
+* Вызов встроенной функции - ```(foo "bar")```. Первый элемент внутри скобок - обязательное имя функции, а далее указываются ее аргументы.
+* Объявление лямбда функции - ```(lambda '(x y) (+ x y))```. После ключевого слова `lambda` стоит список из имен аргументов, за которым следует тело лямбда функции.
+* Аргумент лямбда функции - ```x```. В отличие от атома, строка без символа апострофа (') является ссылкой на имя в текущей области видимости. При объявлении лямбда функции в область видимости тела добавляются имена аргументов, причем при необходимости скрывается имя из объемлющей области видимости.
+* Мир - ```world```.
+
+{% note info %}
+
+Про механизм генерации кода есть [отдельная вводная статья](../../guides/codegen.md). Ниже — справка по конкретным функциям.
+
+{% endnote %}
+
+## FormatCode
+
+Сериализация кода в виде [S-expressions](/docs/s_expressions). Код не должен содержать свободных аргументов функций, т.е. для сериализации кода лямбда функции нужно передавать ее целиком, а не выражения, потенциально содержащие аргументы лямбда функции.
+
+**Примеры:**
+``` yql
+SELECT FormatCode(AtomCode("foo"));
+-- (
+-- (return '"foo")
+-- )
+```
+
+## WorldCode
+
+Построить узел кода с типом `мир`.
+
+**Примеры:**
+``` yql
+SELECT FormatCode(WorldCode());
+-- (
+-- (return world)
+-- )
+```
+
+## AtomCode
+
+Построить узел кода с типом `атом` из строки, переданной в аргумент.
+
+**Примеры:**
+``` yql
+SELECT FormatCode(AtomCode("foo"));
+-- (
+-- (return '"foo")
+-- )
+```
+
+## ListCode
+
+Построить узел кода с типом `список` из набора узлов или списков узлов кода, переданных в аргументы. При этом списки из аргументов встраиваются как отдельно перечисленные узлы кода.
+
+**Примеры:**
+``` yql
+SELECT FormatCode(ListCode(
+ AtomCode("foo"),
+ AtomCode("bar")));
+-- (
+-- (return '('"foo" '"bar"))
+-- );
+
+SELECT FormatCode(ListCode(AsList(
+ AtomCode("foo"),
+ AtomCode("bar"))));
+-- (
+-- (return '('"foo" '"bar"))
+-- )
+```
+
+## FuncCode
+
+Построить узел кода с типом `вызов встроенной функции` из строки с именем функции и набора узлов или списков узлов кода, переданных в аргументы. При этом списки из аргументов встраиваются как отдельно перечисленные узлы кода.
+
+**Примеры:**
+``` yql
+SELECT FormatCode(FuncCode(
+ "Baz",
+ AtomCode("foo"),
+ AtomCode("bar")));
+-- (
+-- (return (Baz '"foo" '"bar"))
+-- )
+
+SELECT FormatCode(FuncCode(
+ "Baz",
+ AsList(
+ AtomCode("foo"),
+ AtomCode("bar"))));
+-- (
+-- (return (Baz '"foo" '"bar"))
+-- )
+```
+
+## LambdaCode
+
+Построить узел кода с типом `объявление лямбда функции` можно из:
+
+* [Лямбда функции](../../syntax/expressions.md#lambda), если заранее известно количество аргументов. В этом случае в качестве аргументов этой лямбда функции будут переданы узлы типа `аргумент`.
+* Количества аргументов и [лямбда функции](../../syntax/expressions.md#lambda) с одним аргументом. В этом случае в качестве аргумента этой лямбды функции будет передан список узлов типа `аргумент`.
+
+**Примеры:**
+``` yql
+SELECT FormatCode(LambdaCode(($x, $y) -> {
+ RETURN FuncCode("+", $x, $y);
+}));
+-- (
+-- (return (lambda '($1 $2) (+ $1 $2)))
+-- )
+
+SELECT FormatCode(LambdaCode(2, ($args) -> {
+ RETURN FuncCode("*", Unwrap($args[0]), Unwrap($args[1]));
+}));
+-- (
+-- (return (lambda '($1 $2) (* $1 $2)))
+-- )
+```
+
+## EvaluateCode
+
+Подстановка в основную программу узла кода, переданного в аргумент.
+
+**Примеры:**
+``` yql
+SELECT EvaluateCode(FuncCode("Int32", AtomCode("1"))); -- 1
+
+$lambda = EvaluateCode(LambdaCode(($x, $y) -> {
+ RETURN FuncCode("+", $x, $y);
+}));
+SELECT $lambda(1, 2); -- 3
+```
+
+## ReprCode
+
+Подстановка в основную программу узла кода, который является представлением результата вычисления выражения, переданного в аргумент.
+
+**Примеры:**
+``` yql
+$add3 = EvaluateCode(LambdaCode(($x) -> {
+ RETURN FuncCode("+", $x, ReprCode(1 + 2));
+}));
+SELECT $add3(1); -- 4
+```
+
+## QuoteCode
+
+Подстановка в основную программу узла кода, который является представлением выражения или [лямбда функции](../../syntax/expressions.md#lambda), переданной в аргумент. Если во время подстановки были найдены свободные аргументы лямбда функций, то они вычисляются и подставляются в код как в функции [ReprCode](#reprcode).
+
+**Примеры:**
+``` yql
+$lambda = ($x, $y) -> { RETURN $x + $y };
+$makeClosure = ($y) -> {
+ RETURN EvaluateCode(LambdaCode(($x) -> {
+ RETURN FuncCode("Apply", QuoteCode($lambda), $x, ReprCode($y))
+ }))
+};
+
+$closure = $makeClosure(2);
+SELECT $closure(1); -- 3
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/dict.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/dict.md
new file mode 100644
index 00000000000..19813b36772
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/dict.md
@@ -0,0 +1,273 @@
+# Функции для работы со словарями
+
+## DictCreate {#dictcreate}
+
+Сконструировать пустой словарь. Передается два аргумента — для ключа и значения, в каждом из которых указывается строка с описанием типа данных, либо сам тип, полученный с помощью [предназначенных для этого функций](../types.md). Словарей с неизвестным типом ключа или значения в YQL не бывает. В качестве ключа может быть задан [примитивный тип данных](../../types/primitive.md) за исключением `Yson` и `Json` с необязательным признаком [опциональности](../../types/optional.md), или кортеж из них длины не менее два.
+
+[Документация по формату описания типа](../../types/type_string.md).
+
+**Примеры**
+``` yql
+SELECT DictCreate(String, Tuple<String,Double?>);
+```
+
+``` yql
+SELECT DictCreate(Tuple<Int32?,String>, OptionalType(DataType("String")));
+```
+
+## SetCreate {#setcreate}
+
+Сконструировать пустое множество. Передается аргумент - тип ключа, возможно, полученный с помощью [предназначенных для этого функций](../types.md). Множеств с неизвестным типом ключа в YQL не бывает. В качестве ключа может быть задан [примитивный тип данных](../../types/primitive.md) за исключением `Yson` и `Json` с необязательным признаком [опциональности](../../types/optional.md), или кортеж из них длины не менее два.
+
+[Документация по формату описания типа](../../types/type_string.md).
+
+**Примеры**
+``` yql
+SELECT SetCreate(String);
+```
+
+``` yql
+SELECT SetCreate(Tuple<Int32?,String>);
+```
+
+## DictLength {#dictlength}
+
+Количество элементов в словаре.
+
+**Примеры**
+``` yql
+SELECT DictLength(AsDict(AsTuple(1, AsList("foo", "bar"))));
+```
+{% if feature_column_container_type %}
+``` yql
+SELECT DictLength(dict_column) FROM my_table;
+```
+{% endif %}
+## DictHasItems {#dicthasitems}
+
+Проверка того, что словарь содержит хотя бы один элемент.
+
+**Примеры**
+``` yql
+SELECT DictHasItems(AsDict(AsTuple(1, AsList("foo", "bar")))) FROM my_table;
+```
+{% if feature_column_container_type %}
+``` yql
+SELECT DictHasItems(dict_column) FROM my_table;
+```
+{% endif %}
+
+
+## DictItems {#dictitems}
+
+Получение содержимого словаря в виде списка кортежей с парами ключ-значение (`List<Tuple<key_type,value_type>>`).
+
+**Примеры**
+
+``` yql
+SELECT DictItems(AsDict(AsTuple(1, AsList("foo", "bar"))));
+-- [ ( 1, [ "foo", "bar" ] ) ]
+```
+{% if feature_column_container_type %}
+``` yql
+SELECT DictItems(dict_column)
+FROM my_table;
+```
+{% endif %}
+## DictKeys {#dictkeys}
+
+Получение списка ключей словаря.
+
+**Примеры**
+
+``` yql
+SELECT DictKeys(AsDict(AsTuple(1, AsList("foo", "bar"))));
+-- [ 1 ]
+```
+{% if feature_column_container_type %}
+``` yql
+SELECT DictKeys(dict_column)
+FROM my_table;
+```
+{% endif %}
+## DictPayloads {#dictpayloads}
+
+Получение списка значений словаря.
+
+**Примеры**
+
+``` yql
+SELECT DictPayloads(AsDict(AsTuple(1, AsList("foo", "bar"))));
+-- [ [ "foo", "bar" ] ]
+```
+{% if feature_column_container_type %}
+``` yql
+SELECT DictPayloads(dict_column)
+FROM my_table;
+```
+{% endif %}
+
+## DictLookup {#dictlookup}
+
+Получение элемента словаря по ключу.
+
+**Примеры**
+
+``` yql
+SELECT DictLookup(AsDict(
+ AsTuple(1, AsList("foo", "bar")),
+ AsTuple(2, AsList("bar", "baz"))
+), 1);
+-- [ "foo", "bar" ]
+```
+{% if feature_column_container_type %}
+``` yql
+SELECT DictLookup(dict_column, "foo")
+FROM my_table;
+```
+{% endif %}
+
+## DictContains {#dictcontains}
+
+Проверка наличия элемента в словаре по ключу. Возвращает true или false.
+
+**Примеры**
+
+``` yql
+SELECT DictContains(AsDict(
+ AsTuple(1, AsList("foo", "bar")),
+ AsTuple(2, AsList("bar", "baz"))
+), 42);
+-- false
+```
+{% if feature_column_container_type %}
+``` yql
+SELECT DictContains(dict_column, "foo")
+FROM my_table;
+```
+{% endif %}
+
+## DictAggregate {#dictaggregate}
+
+Применить [фабрику агрегационных функций](../basic.md#aggregationfactory) для переданного словаря, в котором каждое значение является списком. Фабрика применяется отдельно внутри каждого ключа.
+Если список является пустым, то результат агрегации будет такой же, как для пустой таблицы: 0 для функции `COUNT` и `NULL` для других функций.
+Если в переданном словаре список по некоторому ключу является пустым, то такой ключ удаляется из результата.
+Если переданный словарь является опциональным и содержит значение `NULL`, то в результате также будет `NULL`.
+
+Аргументы:
+
+1. Словарь;
+2. [Фабрика агрегационных функций](../basic.md#aggregationfactory).
+
+
+**Примеры**
+
+```sql
+SELECT DictAggregate(AsDict(
+ AsTuple(1, AsList("foo", "bar")),
+ AsTuple(2, AsList("baz", "qwe"))),
+ AggregationFactory("Max"));
+-- {1 : "foo", 2 : "qwe" }
+
+```
+
+## SetIsDisjoint {#setisjoint}
+
+Проверка того, что словарь и список или другой словарь не пересекаются по ключам.
+
+Таким образом есть два варианта вызова:
+
+* С аргументами `Dict<K,V1>` и `List<K>`;
+* С аргументами `Dict<K,V1>` и `Dict<K,V2>`.
+
+**Примеры**
+
+```sql
+SELECT SetIsDisjoint(ToSet(AsList(1, 2, 3)), AsList(7, 4)); -- true
+SELECT SetIsDisjoint(ToSet(AsList(1, 2, 3)), ToSet(AsList(3, 4))); -- false
+```
+
+## SetIntersection {#setintersection}
+
+Строит пересечение двух словарей по ключам.
+
+Аргументы:
+
+* Два словаря: `Dict<K,V1>` и `Dict<K,V2>`.
+* Необязательная функция, которая объединяет значения из исходных словарей для построения значений выходного словаря. Если тип такой функции `(K,V1,V2) -> U`, то типом результата будет `Dict<K,U>`. Если функция не задана, типом результата будет `Dict<K,Void>`, а значения из исходных словарей игнорируются.
+
+**Примеры**
+``` yql
+SELECT SetIntersection(ToSet(AsList(1, 2, 3)), ToSet(AsList(3, 4))); -- { 3 }
+SELECT SetIntersection(
+ AsDict(AsTuple(1, "foo"), AsTuple(3, "bar")),
+ AsDict(AsTuple(1, "baz"), AsTuple(2, "qwe")),
+ ($k, $a, $b) -> { RETURN AsTuple($a, $b) });
+-- { 1 : ("foo", "baz") }
+```
+
+## SetIncludes {#setincludes}
+
+Проверка того, что в ключи заданного словаря входят все элементы списка или ключи второго словаря.
+
+Таким образом есть два варианта вызова:
+
+* С аргументами `Dict<K,V1>` и `List<K>`;
+* С аргументами `Dict<K,V1>` и `Dict<K,V2>`.
+
+**Примеры**
+``` yql
+SELECT SetIncludes(ToSet(AsList(1, 2, 3)), AsList(3, 4)); -- false
+SELECT SetIncludes(ToSet(AsList(1, 2, 3)), ToSet(AsList(2, 3))); -- true
+```
+
+## SetUnion {#setunion}
+
+Строит объединение двух словарей по ключам.
+
+Аргументы:
+
+* Два словаря: `Dict<K,V1>` и `Dict<K,V2>`.
+* Необязательная функция, которая объединяет значения из исходных словарей для построения значений выходного словаря. Если тип такой функции `(K,V1?,V2?) -> U`, то типом результата будет `Dict<K,U>`. Если функция не задана, типом результата будет `Dict<K,Void>`, а значения из исходных словарей игнорируются.
+
+**Примеры**
+``` yql
+SELECT SetUnion(ToSet(AsList(1, 2, 3)), ToSet(AsList(3, 4))); -- { 1, 2, 3, 4 }
+SELECT SetUnion(
+ AsDict(AsTuple(1, "foo"), AsTuple(3, "bar")),
+ AsDict(AsTuple(1, "baz"), AsTuple(2, "qwe")),
+ ($k, $a, $b) -> { RETURN AsTuple($a, $b) });
+-- { 1 : ("foo", "baz"), 2 : (null, "qwe"), 3 : ("bar", null) }
+```
+
+## SetDifference {#setdifference}
+
+Строит словарь, в котором есть все ключи с соответствующими значениями первого словаря, для которых нет ключа во втором словаре.
+
+**Примеры**
+``` yql
+SELECT SetDifference(ToSet(AsList(1, 2, 3)), ToSet(AsList(3, 4))); -- { 1, 2 }
+SELECT SetDifference(
+ AsDict(AsTuple(1, "foo"), AsTuple(2, "bar")),
+ ToSet(AsList(2, 3)));
+-- { 1 : "foo" }
+```
+
+## SetSymmetricDifference {#setsymmetricdifference}
+
+Строит симметрическую разность двух словарей по ключам.
+
+Аргументы:
+
+* Два словаря: `Dict<K,V1>` и `Dict<K,V2>`.
+* Необязательная функция, которая объединяет значения из исходных словарей для построения значений выходного словаря. Если тип такой функции `(K,V1?,V2?) -> U`, то типом результата будет `Dict<K,U>`. Если функция не задана, типом результата будет `Dict<K,Void>`, а значения из исходных словарей игнорируются.
+
+**Примеры**
+``` yql
+SELECT SetSymmetricDifference(ToSet(AsList(1, 2, 3)), ToSet(AsList(3, 4))); -- { 1, 2, 4 }
+SELECT SetSymmetricDifference(
+ AsDict(AsTuple(1, "foo"), AsTuple(3, "bar")),
+ AsDict(AsTuple(1, "baz"), AsTuple(2, "qwe")),
+ ($k, $a, $b) -> { RETURN AsTuple($a, $b) });
+-- { 2 : (null, "qwe"), 3 : ("bar", null) }
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/index.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/index.md
new file mode 100644
index 00000000000..ae9e3b73433
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/index.md
@@ -0,0 +1,16 @@
+# Встроенные функции YQL
+
+- [Базовые](../basic.md)
+- [Агрегатные](../aggregation.md)
+{% if feature_window_functions %}
+- [Оконные](../window.md)
+{% endif %}
+- [Для работы со списками](../list.md)
+- [Для работы со словарями](../dict.md)
+- [Для работы со структурами](../struct.md)
+- [Для работы с типами](../types.md)
+{% if feature_codegen %}
+- [Для работы с генерацией кода](../codegen.md)
+{% endif %}
+- [Для работы с JSON](../json.md)
+- [Библиотеки C++](../../udf/list/index.md)
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/json.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/json.md
new file mode 100644
index 00000000000..d3dcee71631
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/json.md
@@ -0,0 +1,1156 @@
+# Функции для работы с JSON
+
+**JSON** - слабо схематизированный [формат данных](https://www.json.org), представленный в YQL типом `Json`. В отличии от реляционных таблиц, JSON может хранить данные, для которых схема не определена. Вот пример валидного JSON:
+```json
+[
+ {
+ "name": "Jim Holden",
+ "age": 30
+ },
+ {
+ "name": "Naomi Nagata",
+ "age": "twenty years old"
+ }
+]
+```
+Несмотря на то, что в первом объекте поле `age` имеет тип `Number` (`"age": 21`), а во втором `String` (`"age": "twenty years old"`), это полностью валидный JSON.
+
+Для работы с JSON, YQL реализует подмножество стандарта [SQL support for JavaScript Object Notation (JSON)](https://www.iso.org/standard/67367.html), являющегося частью общепринятого стандарта ANSI SQL.
+
+## Cookbook
+
+```
+$json = CAST(@@{
+ "friends": [
+ {
+ "name": "James Holden",
+ "age": 35
+ },
+ {
+ "name": "Naomi Nagata",
+ "age": 30
+ }
+ ]
+}@@ AS Json);
+
+SELECT
+ JSON_EXISTS($json, "$.friends[*].name"), -- True,
+ JSON_VALUE($json, "$.friends[0].age"), -- "35" (тип Utf8?)
+ JSON_QUERY($json, "$.friends[0]"); -- {"name": "James Holden", "age": 35}
+
+```
+
+### Обращение к полю в базе данных
+В таблицах данные могут хранить в JSON или в строковом представлении. Функции JSON_* для работы ожидают на вход JSON. Для преобразования `String->JSON` нужно воспользоваться функцией `CAST`, например `CAST (my_string AS JSON)`.
+
+## JsonPath
+
+Для обращения к значениям внутри JSON используется язык запросов JsonPath. Все функции для работы с JSON принимают JsonPath запрос в качестве аргумента.
+
+Сразу разберем пример. Пусть у нас есть JSON:
+```json
+{
+ "comments": [
+ {
+ "id": 123,
+ "text": "A whisper will do, if it's all that you can manage."
+ },
+ {
+ "id": 456,
+ "text": "My life has become a single, ongoing revelation that I haven’t been cynical enough."
+ }
+ ]
+}
+```
+
+Тогда чтобы получить текст второго комментария можно написать JsonPath запрос:
+```
+$.comments[1].text
+```
+
+В этом запросе:
+
+1. `$` - это способ обратиться ко всему JSON
+2. `$.comments` - обращение к ключу `comments` объекта JSON
+3. `$.comments[1]` - обращение ко второму элементу массива JSON (нумерация с элементов начинается с 0)
+4. `$.comments[1].text` - обращение к ключу `text` объекта JSON
+5. Результат выполнения: `"My life has become a single, ongoing revelation that I haven’t been cynical enough."`
+
+### Quick reference
+
+| Операция | Пример |
+|-----------------------------------------|-------------------------------------------------|
+| Извлечь ключ JSON объекта | `$.key` |
+| Извлечь все ключи JSON объекта | `$.*` |
+| Обращение к элементу массива | `$[25]` |
+| Извлечение подотрезка массива | `$[2 to 5]` |
+| Обращение к последнему элементу массива | `$[last]` |
+| Обращение ко всем элементам массива | `$[*]` |
+| Унарные операции | `- 1` |
+| Бинарные операции | `(12 * 3) % 4 + 8` |
+| Обращение к переменной | `$variable` |
+| Логические операции | `(1 > 2) &#124;&#124; (3 <= 4) && ("string" == "another")&#124; |
+| Соответствие регулярному выражению | `$.name like_regex "^[A-Za-z]+$"` |
+| Проверка префикса строки | `$.name starts with "Bobbie"` |
+| Проверка существования пути | `exists ($.profile.name)` |
+| Проверка булевского выражения на null | `($.age > 20) is unknown` |
+| Фильтрация значений | `$.friends ? (@.age >= 18 && @.gender == "male")` |
+| Получение типа значения | `$.name.type()` |
+| Получение размера массива | `$.friends.size()` |
+| Преобразование строки в число | `$.number.double()` |
+| Округление числа вверх | `$.number.ceiling()` |
+| Округление числа вниз | `$.number.floor()` |
+| Абсолютное значение числа | `$.number.abs()` |
+| Получение пар ключ-значения из объекта | `$.profile.keyvalue()` |
+
+### Модель данных
+
+Результат выполнения всех JsonPath выражений - это последовательность JSON значений. Например:
+
+- Результат выражения `"Bobbie"` - это последовательность длины 1 с единственным элементом `"Bobbie"`.
+- Результат выражения `$` (взятие всего JSON объекта) на JSON `[1, 2, 3]` - это `[1, 2, 3]`. Последовательность из 1 элемента, массива `[1, 2, 3]`
+- Результат выражения `$[*]` (извлечение всех элементов массива) на JSON `[1, 2, 3]` - это `1, 2, 3`. Последовательность из трех элементов `1`, `2` и `3`
+
+Если входная последовательность состоит из нескольких значений, некоторые операции исполнятся для каждого элемента (например, доступ к ключу JSON объекта). При этом другие операции требуют последовательности из одного элемента на вход (например, бинарные арифметические операции).
+
+Поведение конкретной операции описано в соответствующей секции документации.
+
+### Режим выполнения
+
+JsonPath поддерживает два режима выполнения - `lax` и `strict`. Указание режима не обязательно, по умолчанию используется `lax`. Режим указывается в начале запроса, например: `strict $.key`.
+
+Поведение при каждом режиме описано в разделе соответствующих JsonPath операций.
+
+#### Автоматическая распаковка массива
+
+При обращении к ключу JSON объекта в `lax` режиме массивы автоматически распаковываются.
+
+**Пример:**
+```json
+[
+ {
+ "key": 123
+ },
+ {
+ "key": 456
+ }
+]
+```
+
+Запрос `lax $.key` успешно выполнится с результатом `123, 456`. Поскольку `$` является массивом, он автоматически распакуется, и обращение к ключу JSON объекта `$.key` будет выполнено для каждого элемента массива.
+
+При этом запрос `strict $.key` завершится с ошибкой. В `strict` режиме нет автоматической распаковки массивов. `$` является массивом, а не объектом, поэтому обращение к ключу объекта `$.key` не может быть выполнено. Это можно исправить, написав `strict $[*].key`.
+
+Распаковка происходит только на 1 уровень вглубь. В случае вложенных массивов распаковывается только самый внешний из них.
+
+#### Обертка в массив
+
+При обращении к элементу массива в `lax` режиме JSON значения автоматически оборачиваются в массив.
+
+**Пример:**
+```json
+{
+ "name": "Avasarala"
+}
+```
+
+Запрос `lax $[0].name` выполнится успешно с результатом `"Avasarala"`. Поскольку `$` не является массивом, он будет автоматически обернут в массив длины один. Обращение к первому элементу `$[0]` вернет исходный JSON объект, в котором будет взят ключ `name`.
+
+При этом запрос `strict $[0].name` завершится с ошибкой. В `strict` режиме нет автоматической обертки в массив. `$` является объектом, а не массивом, поэтому обращение к элементу `$[0]` не может быть выполнено. Это можно исправить, написав `strict $.name`.
+
+#### Обработка ошибок
+
+Некоторые ошибки конвертируются в пустой результат при выполнении в `lax` режиме.
+
+### Литералы
+
+Значения некоторых типов можно указать в JsonPath запросе используя литералы:
+
+| Тип | Пример |
+| ------------------ | ---------------- |
+| Числа | `42`, `-1.23e-5` |
+| Булевские значения | `false`, `true` |
+| Null | `null` |
+| Строки | `"Belt"` |
+
+### Обращение к ключу JSON объекта
+
+JsonPath поддерживает обращение к ключам JSON объектов: `$.session.user.name`.
+
+{% note info %}
+
+Обращение без кавычек можно использовать только для ключей, которые начинаются с буквы английского алфавита или подчеркивания, и содержат в себе только буквы английского алфавита, подчеркивания, цифры и знак доллара. Для всех остальных ключей необходимо использовать кавычки. Например: `$.profile."this string has spaces"`, `$.user."42 is the answer"`
+
+{% endnote %}
+
+Для каждого значения из входной последовательности:
+
+1. Если значение является массивом, в `lax` режиме происходит автоматическая распаковка массива
+2. Если значение не является JSON объектом или указанный ключ в этом JSON объекте отсутствует, в `strict` режиме запрос завершается ошибкой. В `lax` режиме для этого значения возвращается пустой результат
+
+Результат выражения - конкатенация результатов для каждого значения из входной последовательности.
+
+**Пример:**
+```json
+{
+ "name": "Amos",
+ "friends": [
+ {
+ "name": "Jim"
+ },
+ {
+ "name": "Alex"
+ }
+ ]
+}
+```
+
+| | `lax` | `strict` |
+|------------------|------------------|----------|
+| `$.name` | `"Amos"` | `"Amos"` |
+| `$.surname` | Пустой результат | Ошибка |
+| `$.friends.name` | `"Jim", "Alex"` | Ошибка |
+
+### Обращение ко всем ключам JSON объекта
+
+JsonPath поддерживает обращение ко всем ключам JSON объектов сразу: `$.*`.
+
+Для каждого значения из входной последовательности:
+
+1. Если значение является массивом, в `lax` режиме происходит автоматическая распаковка массива
+2. Если значение не является JSON объектом, в `strict` режиме запрос завершается ошибкой. В `lax` режиме для этого значения возвращается пустой результат
+
+Результат выражения - конкатенация результатов для каждого значения из входной последовательности.
+
+**Пример:**
+```json
+{
+ "profile": {
+ "id": 123,
+ "name": "Amos"
+ },
+ "friends": [
+ {
+ "name": "Jim"
+ },
+ {
+ "name": "Alex"
+ }
+ ]
+}
+```
+
+| | `lax` | `strict` |
+| ------------- | --------------- | ------------- |
+| `$.profile.*` | `123, "Amos"` | `123, "Amos"` |
+| `$.friends.*` | `"Jim", "Alex"` | Ошибка |
+
+### Обращение к элементу массива
+
+JsonPath поддерживает обращение к элементам массивов: `$.friends[1, 3 to last - 1]`.
+
+Для каждого значения из входной последовательности:
+
+1. Если значение не является массивом, то в `strict` режиме запрос завершается ошибкой. В `lax` режиме происходит автоматическая обертка в массив
+2. Ключевое слово `last` заменяется на последний индекс массива. Использование `last` вне обращения к массиву - это ошибка в обоих режимах
+3. Вычисляются указанные индексы. Каждый из них должен быть единственным числом, иначе запрос завершается ошибкой в обоих режимах
+4. Если индекс является дробным числом, он округляется вниз
+5. Если индекс выходит за границы массива, то в `strict` режиме запрос завершается ошибкой. В `lax` режиме такой индекс игнорируется
+6. Если указан отрезок и его стартовый индекс больше конечного индекса (например `$[20 to 1]`), то в `strict` режиме запрос завершается ошибкой. В `lax` режиме такой отрезок игнорируется.
+7. К результату добавляются все элементы по указанным индексам. Отрезки включают в себя **оба конца**
+
+**Примеры**:
+```json
+[
+ {
+ "name": "Camina",
+ "surname": "Drummer"
+ },
+ {
+ "name": "Josephus",
+ "surname": "Miller"
+ },
+ {
+ "name": "Bobbie",
+ "surname": "Draper"
+ },
+ {
+ "name": "Julie",
+ "surname": "Mao"
+ }
+]
+```
+
+| | `lax` | `strict` |
+| ----------------------------- | ------------------------------- | ------------------------------- |
+| `$[0].name` | `"Camina"` | `"Camina"` |
+| `$[1, 2 to 3].name` | `"Josephus", "Bobbie", "Julie"` | `"Josephus", "Bobbie", "Julie"` |
+| `$[last - 2].name` | `"Josephus"` | `"Josephus"` |
+| `$[2, last + 200 to 50].name` | `"Bobbie"` | Ошибка |
+| `$[50].name` | Пустой результат | Ошибка |
+
+### Обращение ко всем элементам массива
+
+JsonPath поддерживает обращение ко всем элементам массива сразу: `$[*]`.
+
+Для каждого значения из входной последовательности:
+
+1. Если значение не является массивом, то в `strict` режиме запрос завершается ошибкой. В `lax` режиме происходит автоматическая обертка в массив
+2. К результату добавляются все элементы текущего массива
+
+**Примеры:**
+```json
+[
+ {
+ "class": "Station",
+ "title": "Medina"
+ },
+ {
+ "class": "Corvette",
+ "title": "Rocinante"
+ }
+]
+```
+
+| | `lax` | `strict` |
+| ------------------- | ------------------------- | ----------------------- |
+| `$[*].title` | `"Medina", "Rocinante"` | `"Medina", "Rocinante"` |
+| `lax $[0][*].class` | `"Station"` | Ошибка |
+
+Разберем последний пример по шагам:
+
+1. `$[0]` возвращает первый элемент массива, то есть `{"class": "Station", "title": "Medina"}`
+2. `$[0][*]` ожидает массив на вход, но был дан объект. Происходит автоматическая обертка в массив, получается `[ {"class": "Station", "title": "Medina"} ]`
+3. Теперь `$[0][*]` может выполниться и возвращает все элементы массива, то есть `{"class": "Station", "title": "Medina"}`
+4. `$[0][*].class` возвращает поле `class`, то есть `"Station"`.
+
+### Арифметические операции
+
+{% note info %}
+
+Все арифметические операции работают с числами как с Double. Возможна [потеря точности](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) при вычислениях.
+
+{% endnote %}
+
+#### Унарные операции
+
+JsonPath поддерживает унарный `+` и `-`.
+
+Унарная операция применяется ко всем значениям из входной последовательности. Если унарной операции подать на вход не число, запрос завершится ошибкой в обоих режимах.
+
+**Пример:**
+```json
+[1, 2, 3, 4]
+```
+
+Запрос `strict -$[*]` завершится успешно с результатом `-1, -2, -3, -4`.
+
+Запрос `lax -$` завершится с ошибкой, потому что `$` является массивом, а не числом.
+
+#### Бинарные операции
+
+JsonPath поддерживает бинарные арифметические операции (в порядке убывания приоритета):
+
+1. Умножение `*`, деление чисел с плавающей точкой `/`, взятие остатка `%` (работает как функция `MOD` в `SQL`)
+2. Сложение `+`, вычитание `-`
+
+Порядок выполнения операций можно поменять используя скобочки.
+
+В случае если каждый аргумент бинарной операции не является единственным числом или происходит деление на ноль, запрос завершается ошибкой в обоих режимах.
+
+**Примеры:**
+
+- `(1 + 2) * 3` даст `9`
+- `1 / 2` даст `0.5`
+- `5 % 2` даст `1`
+- `1 / 0` завершится ошибкой
+- При JSON `[-32.4, 5.2]` запрос `$[0] % $[1]` даст `-1.2`
+- При JSON `[1, 2, 3, 4]` запрос `lax $[*] + $[*]` завершится ошибкой, так как результат выражения `$[*]` - это `1, 2, 3, 4`, несколько чисел. Бинарная операция требует только одно число для каждого своего аргумента.
+
+### Булевские значения
+
+В отличии от некоторых языков программирования, в JsonPath булевскими значениями считаются не только `true` (истина) и `false` (ложь), но и `null` (неопределенность).
+
+JsonPath считает все значения, полученные из JSON документа, не булевскими. Например, запрос `! $.is_valid_user` (логическое отрицание, примененное к полю `is_valid_user`), является синтаксически неверным поскольку поле `is_valid_user` не является булевским значением (даже если по факту в нем хранится `true` или `false`). Правильный способ написать такой запрос - это явно использовать сравнение с булевским значением, например `$.is_valid_user == false`.
+
+### Логические операции
+
+JsonPath поддерживает некоторые логические операции для работы с булевскими значениями.
+
+Аргументы всех логических операций должны являться единственным булевским значением.
+Все логические операции возвращают булевское значение.
+
+**Логическое отрицание, `!`**
+
+Таблица истинности:
+
+| `x` | `!x` |
+| ------- | ------- |
+| `true` | `false` |
+| `false` | `true` |
+| `null` | `null` |
+
+**Логическое И, `&&`**
+
+Таблица истинности, первый столбец это левый аргумент, первая строка это правый аргумент, каждая клетка это результат применения логического И с левым и правым аргументами:
+
+| `&&` | `true` | `false` | `null` |
+| ------- | ------- | ------- | ------- |
+| `true` | `true` | `false` | `null` |
+| `false` | `false` | `false` | `false` |
+| `null` | `null` | `false` | `null` |
+
+**Логическое ИЛИ, `||`**
+
+Таблица истинности, первый столбец это левый аргумент, первая строка это правый аргумент, каждая клетка это результат применения логического ИЛИ с левым и правым аргументами:
+
+| `||` | `true` | `false` | `null` |
+| ------- | ------- | ------- | ------- |
+| `true` | `true` | `true` | `true` |
+| `false` | `true` | `false` | `null` |
+| `null` | `true` | `null` | `null` |
+
+**Примеры:**
+
+- `! (true == true)`, результат `false`
+- `(true == true) && (true == false)`, результат `false`
+- `(true == true) || (true == false)`, результат `true`
+
+### Операторы сравнения
+
+JsonPath реализует операторы сравнения для значений:
+
+- Равенство, `==`
+- Неравенство, `!=` и `<>`
+- Меньше и меньше либо равно, `<` и `<=`
+- Больше и больше либо равно, `>` и `>=`
+
+Все операторы сравнения возвращают булевское значение. Оба аргумента оператора поддерживают наличие нескольких значений.
+
+Если при вычислении аргументов оператора возникла ошибка, оператор возвращает `null`. При этом выполнение JsonPath запроса продолжается.
+
+Для каждого из аргументов производится автоматическая распаковка массивов. После этого для каждой пары, где первый элемент берется из последовательности левого аргумента, а второй элемент из последовательности правого аргумента:
+
+1. Выполняется сравнение элементов пары
+2. Если при сравнении возникла ошибка, устанавливается флаг `ERROR`
+3. Если результат сравнения это истина, устанавливается флаг `FOUND`
+4. Если один из флагов `ERROR` или `FOUND` установлен и запрос исполняется в `lax` режиме, больше никакие пары не рассматриваются
+
+Если после рассмотрения пар:
+
+1. Установлен флаг `ERROR`, оператор возвращает `null`
+2. Установлен флаг `FOUND`, оператор возвращает `true`
+3. Иначе оператор возвращает `false`
+
+Можно сказать что данный алгоритм рассматривает все пары из декартового произведения левого и правого аргумента, пытаясь найти ту, сравнение которой вернет истину.
+
+Сравнение элементов в паре производится по следующим правилам:
+
+1. Если левый или правый аргумент являются массивом или объектом, сравнение завершается с ошибкой
+2. `null == null` возвращает истину
+3. Во всех остальных случаях если один из аргументов `null`, возвращается ложь
+4. Если левый и правый аргумент разных типов, сравнение завершается с ошибкой
+5. Строки сравниваются побайтово
+6. `true` считается больше `false`
+7. Числа сравниваются с точностью `1e-20`
+
+**Пример:**
+
+Для примера рассмотрим JSON документ
+
+```json
+{
+ "left": [1, 2],
+ "right": [4, "Inaros"]
+}
+```
+
+и разберем по шагам выполнение запроса `lax $.left < $.right`:
+
+1. Автоматическая распаковка массивов в левом и правом аргументе. В качестве левого аргумента получаем последовательность `1, 2`, в качестве правого `4, "Iranos"`
+2. Рассматриваем пару `(1, 4)`. Сравнение проходит успешно, `1 < 4` это истина. Устанавливаем флаг `FOUND`
+3. Поскольку выполнение происходит в `lax` режиме и установлен флаг `FOUND`, больше никакие пары мы не рассматриваем
+4. Поскольку установлен флаг `FOUND`, оператор возвращает истину
+
+Разберем тот же запрос, но в другом режиме выполнения: `strict $.left < $.right`:
+
+1. Автоматическая распаковка массивов в левом и правом аргументе. В качестве левого аргумента получаем последовательность `1, 2`, в качестве правого `4, "Iranos"`
+2. Рассматриваем пару `(1, 4)`. Сравнение проходит успешно, `1 < 4` это истина. Устанавливаем флаг `FOUND`
+3. Рассматриваем пару `(2, 4)`. Сравнение проходит успешно, `2 < 4` это истина. Устанавливаем флаг `FOUND`
+4. Рассматриваем пару `(1, "Iranos")`. Сравнение завершается ошибкой (число нельзя сравнить со строкой). Устанавливаем флаг `ERROR`
+5. Рассматриваем пару `(2, "Iranos")`. Сравнение завершается ошибкой (число нельзя сравнить со строкой). Устанавливаем флаг `ERROR`
+6. Поскольку установлен флаг `ERROR`, оператор возвращает `null`
+
+### Предикаты
+
+JsonPath поддерживает предикаты - выражения, возвращающие булевское значение, и проверяющие некоторое условие. Их можно использовать, например, в фильтрах.
+
+#### `like_regex`
+
+Предикат `like_regex` позволяет проверить строку на соответствие регулярному выражению. Синтаксис регулярных выражений такой же как в [Hyperscan UDF](../../udf/list/hyperscan.md) и [REGEXP](../../syntax/expressions.md#regexp).
+
+**Синтаксис**
+
+```
+<expression> like_regex <regexp string> [flag <flag string>]
+```
+
+Где:
+
+1. `<expression>` - это JsonPath выражение, содержащее строки, которые следует проверить на соответствие регулярному выражению
+2. `<regexp string>` - это строка, содержащая регулярное выражение
+3. `flag <flag string>` - это опциональная секция, в которой `<flag string>` является строкой с флагами для исполнения регулярного выражения
+
+Поддерживаемые флаги:
+
+- `i` - отключение чувствительности к регистру
+
+**Исполнение**
+
+Перед проверкой производится автоматическая распаковка массивов во входной последовательности.
+
+После этого для каждого элемента входной последовательности:
+
+1. Выполняется проверка на соответствие элемента регулярному выражению
+2. Если элемент не является строкой, устанавливается флаг `ERROR`
+3. Если результат проверки это истина, устанавливается флаг `FOUND`
+4. Если один из флагов `ERROR` или `FOUND` установлен и запрос исполняется в `lax` режиме, больше никакие пары не рассматриваются
+
+Если после рассмотрения пар:
+
+1. Установлен флаг `ERROR`, предикат возвращает `null`
+2. Установлен флаг `FOUND`, предикат возвращает `true`
+3. Иначе предикат возвращает `false`
+
+**Примеры**
+
+1. `"123456" like_regex "^[0-9]+$"` возвращает `true`
+2. `"123abcd456" like_regex "^[0-9]+$"` возвращает `false`
+3. `"Naomi Nagata" like_regex "nag"` возвращает `false`
+4. `"Naomi Nagata" like_regex "nag" flag "i"` возвращает `true`
+
+#### `starts with`
+
+Предикат `starts with` позволяет проверить является ли одна строка префиксом другой.
+
+**Синтаксис**
+
+```
+<string expression> starts with <prefix expression>
+```
+
+Где:
+
+1. `<string expression>` - это JsonPath выражение, содержащее строку, которую нужно проверить
+2. `<prefix expression>` - это JsonPath выражение, содержащее строку-префикс
+
+То есть предикат будет проверять что `<string expression>` начинается со строки `<prefix expression>`.
+
+**Исполнение**
+
+Первый аргумент предиката должен быть единственной строкой.
+
+Второй аргумент предиката должен быть последовательностью (возможно, из нескольких) строк.
+
+Для каждого элемента из последовательности строк-префиксов:
+
+1. Выполняется проверка "является ли элемент префиксом входной строки"
+2. Если элемент не является строкой, устанавливается флаг `ERROR`
+3. Если результат проверки это истина, устанавливается флаг `FOUND`
+4. Если один из флагов `ERROR` или `FOUND` установлен и запрос исполняется в `lax` режиме, больше никакие пары не рассматриваются
+
+Если после рассмотрения пар:
+
+1. Установлен флаг `ERROR`, предикат возвращает `null`
+2. Установлен флаг `FOUND`, предикат возвращает `true`
+3. Иначе предикат возвращает `false`
+
+**Примеры**
+
+1. `"James Holden" starts with "James"` возвращает `true`
+2. `"James Holden" starts with "Amos"` возвращает `false`
+
+#### `exists`
+
+Предикат `exists` позволяет проверить, возвращает ли JsonPath выражение хотя бы один элемент.
+
+**Синтаксис**
+
+```
+exists (<expression>)
+```
+
+Где `<expression>` - это JsonPath выражение, которое нужно проверить. Скобки вокруг выражения обязательны.
+
+**Исполнение**
+
+1. Исполняется переданное JsonPath выражение
+2. Если в результате исполнения возникла ошибка, предикат возвращает `null`
+3. Если в результате исполнения была получена пустая последовательность, предикат возвращает `false`
+4. Иначе предикат возвращает `true`
+
+**Примеры**
+
+Рассмотрим JSON документ:
+
+```json
+{
+ "profile": {
+ "name": "Josephus",
+ "surname": "Miller"
+ }
+}
+```
+
+1. `exists ($.profile.name)` возвращает `true`
+2. `exists ($.friends.profile.name)` возвращает `false`
+3. `strict exists ($.friends.profile.name)` возвращает `null`, потому что в `strict` режиме обращение к несуществующим ключам объекта это ошибка
+
+#### `is unknown`
+
+Предикат `is unknown` позволяет проверить, является ли булевское значение `null`.
+
+**Синтаксис**
+
+```
+(<expression>) is unknown
+```
+
+Где `<expression>` - это JsonPath выражение, которое нужно проверить. Допускаются только выражения, возвращающие булевское значение. Скобки вокруг выражения обязательны.
+
+**Исполнение**
+
+1. Если переданное выражение возвращает `null`, предикат возвращает `true`
+2. Иначе предикат возвращает `false`
+
+**Примеры**
+
+1. `(1 == 2) is unknown` возвращает `false`. Выражение `1 == 2` вернуло `false`, что не является `null`
+2. `(1 == "string") is unknown` возвращает `true`. Выражение `1 == "string"` вернуло `null`, поскольку в JsonPath строки и числа не сравнимы
+
+### Фильтры
+
+JsonPath позволяет фильтровать значения, полученные в ходе выполнения запроса.
+
+Выражение в фильтре должно возвращать булевское значение.
+Перед фильтрацией производится автоматическая распаковка массивов во входной последовательности.
+
+Для каждого элемента входной последовательности:
+
+1. Значение текущего фильтруемого объекта `@` становится равным текущему элементу входной последовательности
+2. Исполняется выражение в фильтре
+3. Если в ходе выполнения выражения возникла ошибка, текущий элемент входной последовательности пропускается
+4. Если результат исполнения выражения это единственное значение `true`, текущий элемент добавляется в результат фильтра
+
+**Пример:**
+
+Пусть у нас есть JSON документ, описывающий друзей пользователя
+
+```json
+{
+ "friends": [
+ {
+ "name": "James Holden",
+ "age": 35,
+ "money": 500
+ },
+ {
+ "name": "Naomi Nagata",
+ "age": 30,
+ "money": 345
+ }
+ ]
+}
+```
+
+и мы хотим получить с помощью JsonPath запроса друзей которые старше 32 лет. Для этого можно написать следующий запрос:
+
+```
+$.friends ? (@.age > 32)
+```
+
+Разберем запрос по частям:
+
+- `$.friends` - обращение к массиву `friends` в JSON документе
+- `? ( ... )` - синтаксис фильтра. Выражение внутри скобок называется предикатом
+- `@` - обращение к текущему фильтруемому объекту. В нашем примере это объект, описывающий друга пользователя
+- `@.age` - обращение к полю `age` текущего фильтруемого объекта
+- `@.age > 32` - сравнение поля `age` со значением 32. В результате выполнения запроса останутся только те значения, для которых данный предикат вернул истину
+
+В результате выполнения этого запроса будет получен только первый друг из массива друзей пользователя.
+
+Как и многие другие операторы языка JsonPath, фильтры можно выстраивать в цепочки. Разберем более сложный запрос, который отбирает имена друзей которые старше 20 лет и которые имеют меньше чем 400 единиц валюты:
+
+```
+$.friends ? (@.age > 20) ? (@.money < 400) . name
+```
+
+Разберем запрос по частям:
+
+- `$.friends` - обращение к массиву `friends` в JSON документе
+- `? (@.age > 20)` - первый фильтр. Поскольку все друзья старше 20, он просто вернет все элементы массива `friends`
+- `? (@.money < 400)` - второй фильтр. Вернет только второй элемент массива `friends`, поскольку только у него поле `money` имеет значение меньше 400
+- `.name` - обращение к полю `name` у отфильтрованных объектов
+
+В результате выполнения этого запроса будет получена последовательность из одного элемента - `"Naomi Nagata"`.
+
+На практике рекомендуется объединять несколько фильтров в один если есть такая возможность. Рассмотренный запрос эквивалентен `$.friends ? (@.age > 20 && @.money < 400) . name`.
+
+### Методы
+
+JsonPath поддерживает методы - функции, которые преобразуют одни последовательности значений в другие. Синтаксис вызова метода похож на обращение к ключу объекта:
+
+```
+$.friends.size()
+```
+
+Также как и обращение к ключам объекта, вызовы методов можно выстраивать в цепочки:
+
+```
+$.numbers.double().floor()
+```
+
+#### `type`
+
+Метод `type` возвращает строчку с названием типа переданного значения.
+
+Для каждого элемента входной последовательности метод добавляет строчку в выходную последовательность в соответствии с табличкой:
+
+| Тип значения | Строка с названием типа |
+| ------------------ | ------------------------ |
+| Null | `"null"` |
+| Булевское значение | `"boolean"` |
+| Число | `"number"` |
+| Строка | `"string"` |
+| Массив | `"array"` |
+| Объект | `"object"` |
+
+**Примеры**
+
+1. `"Naomi".type()` возвращает `"string"`
+2. `false.type()` возвращает `"boolean"`
+
+#### `size`
+
+Метод `size` возвращает размер массива.
+
+Для каждого элемента входной последовательности метод добавляет в выходную последовательность:
+
+1. Размер массива, если тип элемента это массив
+2. Для всех остальных типов (включая объекты) `1`
+
+**Примеры**
+
+Рассмотрим JSON документ:
+
+```json
+{
+ "array": [1, 2, 3],
+ "object": {
+ "a": 1,
+ "b": 2
+ },
+ "scalar": "string"
+}
+```
+
+И запросы к нему:
+
+1. `$.array.size()` возвращает `3`
+2. `$.object.size()` возвращает `1`
+3. `$.scalar.size()` возвращает `1`
+
+#### `double`
+
+Метод `double` конвертирует строки в числа.
+
+Перед выполнением производится автоматическая распаковка массивов во входной последовательности.
+
+Все элементы во входной последовательности должны быть строками, которые содержат числа в десятичной записи. Допускается указание дробной части и экспоненты.
+
+**Примеры**
+
+1. `"125".double()` возвращает `125`
+2. `"125.456".double()` возвращает `125.456`
+3. `"125.456e-3".double()` возвращает `0.125456`
+
+#### `ceiling`
+
+Метод `ceiling` округляет числа вверх.
+
+Перед выполнением производится автоматическая распаковка массивов во входной последовательности.
+
+Все элементы во входной последовательности должны быть числами.
+
+**Примеры**
+
+1. `(1.3).ceiling()` возвращает `2`
+2. `(1.8).ceiling()` возвращает `2`
+3. `(1.5).ceiling()` возвращает `2`
+4. `(1.0).ceiling()` возвращает `1`
+
+#### `floor`
+
+Метод `floor` округляет числа вниз.
+
+Перед выполнением производится автоматическая распаковка массивов во входной последовательности.
+
+Все элементы во входной последовательности должны быть числами.
+
+**Примеры**
+
+1. `(1.3).floor()` возвращает `1`
+2. `(1.8).floor()` возвращает `1`
+3. `(1.5).floor()` возвращает `1`
+4. `(1.0).floor()` возвращает `1`
+
+#### `abs`
+
+Метод `abs` вычисляет абсолютное значение числа (убирает знак).
+
+Перед выполнением производится автоматическая распаковка массивов во входной последовательности.
+
+Все элементы во входной последовательности должны быть числами.
+
+**Примеры**
+
+1. `(0.0).abs()` возвращает `0`
+2. `(1.0).abs()` возвращает `1`
+3. `(-1.0).abs()` возвращает `1`
+
+#### `keyvalue`
+
+Метод `keyvalue` конвертирует объект в последовательность пар ключ-значение.
+
+Перед выполнением производится автоматическая распаковка массивов во входной последовательности.
+
+Все элементы во входной последовательности должны быть объектами.
+
+Для каждого элемента входной последовательности:
+
+1. Рассматривается каждая пара ключ-значение в элементе
+2. Для каждой такой пары формируется объект с ключами `name` и `value`
+3. `name` хранит строку с названием ключа из пары
+4. `value` хранит значение из пары
+5. Все объекты для этого элемента добавляются в выходную последовательность
+
+**Примеры**
+
+Рассмотрим JSON документ:
+
+```json
+{
+ "name": "Chrisjen",
+ "surname": "Avasarala",
+ "age": 70
+}
+```
+
+Для него запрос `$.keyvalue()` вернет последовательность:
+
+```json
+{
+ "name": "age",
+ "value": 70
+},
+{
+ "name": "name",
+ "value": "Chrisjen"
+},
+{
+ "name": "surname",
+ "value": "Avasarala"
+}
+```
+
+### Переменные
+
+Функции использующие JsonPath могут передавать значения внутрь запроса, они называются переменными. Чтобы обратиться к переменной, нужно написать символ `$` и название переменной: `$variable`.
+
+**Пример:**
+
+Пусть переменная `planet` равна
+```json
+{
+ "name": "Mars",
+ "gravity": 0.376
+}
+```
+
+Тогда запрос `strict $planet.name` даст `"Mars"`.
+
+В отличии от многих языков программирования, JsonPath не поддерживает создание новых переменных или изменение существующих.
+
+## Общие аргументы
+
+Все функции для работы с JSON принимают:
+
+1. JSON значение (может быть произвольным выражением типа `Json` или `Json?`)
+2. JsonPath запрос (должен быть явно указан строковым литералом)
+3. **(Опционально)** `PASSING` секция
+
+### PASSING секция
+
+Позволяет передавать значения в JsonPath запрос в качестве переменных.
+
+**Синтаксис:**
+``` yql
+PASSING
+ <expression 1> AS <variable name 1>,
+ <expression 2> AS <variable name 2>,
+ ...
+```
+
+`<expression>` может быть следующих типов:
+
+- Числа, `Date`, `DateTime` и `Timestamp` (будет произведен `CAST` в тип `Double` перед передачей в JsonPath)
+- `Utf8`, `Bool` и `Json`
+
+Имя переменной `<variable name>` можно указать несколькими способами:
+
+- Как SQL имя, например `variable`
+- В кавычках, например `"variable"`
+
+**Пример:**
+``` yql
+JSON_VALUE(
+ $json,
+ "$.timestamp - $Now + $Hour"
+ PASSING
+ 24 * 60 as Hour,
+ CurrentUtcTimestamp() as "Now"
+)
+```
+
+## JSON_EXISTS {#json_exists}
+
+Функция `JSON_EXISTS` позволяет проверить удовлетворяет ли JSON значение указанному JsonPath.
+
+**Синтаксис:**
+``` yql
+JSON_EXISTS(
+ <JSON expression>,
+ <JsonPath query>,
+ [<PASSING clause>]
+ [{TRUE | FALSE | UNKNOWN | ERROR} ON ERROR]
+)
+```
+
+**Возвращаемое значение:** `Bool?`
+
+**Значения по умолчанию:** Если `ON ERROR` секция не указана, используется `FALSE ON ERROR`
+
+**Поведение:**
+
+1. Если `<JSON expression>` это `NULL` или пустой `Json?`, то возвращается пустой `Bool?`
+2. Если при выполнении JsonPath возникла ошибка, то возвращаемое значение зависит от `ON ERROR` секции:
+ - `TRUE` - вернуть `True`
+ - `FALSE` - вернуть `False`
+ - `UNKNOWN` - вернуть пустой `Bool?`
+ - `ERROR` - завершить весь запрос с ошибкой
+3. Если результат выполнения JsonPath - это одно или несколько значений, возвращается `True`
+4. Иначе возвращается `False`
+
+**Примеры:**
+
+``` yql
+$json = CAST(@@{
+ "title": "Rocinante",
+ "crew": [
+ "James Holden",
+ "Naomi Nagata",
+ "Alex Kamai",
+ "Amos Burton"
+ ]
+}@@ as Json);
+
+SELECT
+ JSON_EXISTS($json, "$.title"), -- True
+ JSON_EXISTS($json, "$.crew[*]"), -- True
+ JSON_EXISTS($json, "$.nonexistent"); -- False, так как JsonPath вернет пустой результат
+
+SELECT
+ -- Ошибка JsonPath, вернет False, так как по умолчанию используется FALSE ON ERROR
+ JSON_EXISTS($json, "strict $.nonexistent");
+
+SELECT
+ -- Ошибка JsonPath, весь YQL запрос завершится ошибкой
+ JSON_EXISTS($json, "strict $.nonexistent" ERROR ON ERROR);
+```
+
+## JSON_VALUE {#json_value}
+
+Функция `JSON_VALUE` позволяет извлечь из JSON скалярное значение (все что не массив и не объект).
+
+**Синтаксис:**
+``` yql
+JSON_VALUE(
+ <JSON expression>,
+ <JsonPath query>,
+ [<PASSING clause>]
+ [RETURNING <type>]
+ [{ERROR | NULL | DEFAULT <expr>} ON EMPTY]
+ [{ERROR | NULL | DEFAULT <expr>} ON ERROR]
+)
+```
+
+**Возвращаемое значение:** `<type>?`
+
+**Значения по умолчанию:**
+
+1. Если `ON EMPTY` секция не указана, используется `NULL ON EMPTY`
+2. Если `ON ERROR` секция не указана, используется `NULL ON ERROR`
+3. Если `RETURNING` секция не указана, в качестве `<type>` используется `Utf8`
+
+**Поведение:**
+
+1. Если `<JSON expression>` это `NULL` или пустой `Json?`, то возвращается пустой `<type>?`
+2. Если возникла ошибка, то возвращаемое значение зависит от `ON ERROR` секции:
+ - `NULL` - вернуть пустой `<type>?`
+ - `ERROR` - завершить весь запрос с ошибкой
+ - `DEFAULT <expr>` - вернуть `<expr>`, предварительно сделав `CAST` в тип `<type>?`. Если `CAST` не удастся, весь запрос завершится с ошибкой
+3. Если в результате выполнения JsonPath получился пустой результат, то возвращаемое значение зависит от `ON EMPTY` секции:
+ - `NULL` - вернуть пустой `<type>?`
+ - `ERROR` - завершить весь запрос с ошибкой
+ - `DEFAULT <expr>` - вернуть `<expr>`, предварительно сделав `CAST` в тип `<type>?`. Если `CAST` не удастся, то поведение соответствует `ON ERROR` секции
+4. Если результат выполнения JsonPath - это одно значение, то:
+ - Если `RETURNING` секция не была указана, значение конвертируется в `Utf8`
+ - Иначе производится `CAST` значения в `<type>`. Если `CAST` не удастся, то поведение соответствует `ON ERROR` секции. При этом значение из JSON должно "соответствовать" типу `<type>`.
+5. Вернуть полученный результат
+
+Определим соответствие JSON типов YQL типам:
+- JSON Number - числовые типы, `Date`, `DateTime` и `Timestamp`
+- JSON Bool - `Bool`
+- JSON String - `Utf8` и `String`
+
+Ошибками при выполнении `JSON_VALUE` считаются:
+
+- Ошибки во время вычисления JsonPath
+- Результат выполнения JsonPath - это несколько значений или не скалярное значение
+- Тип полученного из JSON значения не совпадает с ожидаемым
+
+`RETURNING` секция поддерживает типы чисел, `Date`, `DateTime`, `Timestamp`, `Utf8`, `String` и `Bool`.
+
+**Примеры:**
+``` yql
+$json = CAST(@@{
+ "friends": [
+ {
+ "name": "James Holden",
+ "age": 35
+ },
+ {
+ "name": "Naomi Nagata",
+ "age": 30
+ }
+ ]
+}@@ as Json);
+
+SELECT
+ JSON_VALUE($json, "$.friends[0].age"), -- "35" (тип Utf8?)
+ JSON_VALUE($json, "$.friends[0].age" RETURNING Uint64), -- 35 (тип Uint64?)
+ JSON_VALUE($json, "$.friends[0].age" RETURNING Utf8); -- пустой Utf8?, так как произошла ошибка. Тип JSON значения Number не соответствует строковому типу Utf8
+
+SELECT
+ -- "empty" (тип String?)
+ JSON_VALUE(
+ $json,
+ "$.friends[50].name"
+ RETURNING String
+ DEFAULT "empty" ON EMPTY
+ );
+
+SELECT
+ -- 20 (тип Uint64?). Результат выполнения JsonPath пустой, но значение
+ -- по умолчанию из секции ON EMPTY не может быть приведено к Uint64.
+ -- Поэтому используется значение из ON ERROR
+ JSON_VALUE(
+ $json,
+ "$.friends[50].age"
+ RETURNING Uint64
+ DEFAULT -1 ON EMPTY
+ DEFAULT 20 ON ERROR
+ );
+
+```
+
+## JSON_QUERY {#json_query}
+
+Функция `JSON_QUERY` позволяет извлекать из JSON массивы и объекты.
+
+**Синтаксис:**
+``` yql
+JSON_QUERY(
+ <JSON expression>,
+ <JsonPath query>,
+ [<PASSING clause>]
+ [WITHOUT [ARRAY] | WITH [CONDITIONAL | UNCONDITIONAL] [ARRAY] WRAPPER]
+ [{ERROR | NULL | EMPTY ARRAY | EMPTY OBJECT} ON EMPTY]
+ [{ERROR | NULL | EMPTY ARRAY | EMPTY OBJECT} ON ERROR]
+)
+```
+
+**Возвращаемое значение:** `Json?`
+
+**Значения по умолчанию:**
+
+1. Если `ON EMPTY` секция не указана, используется `NULL ON EMPTY`
+2. Если `ON ERROR` секция не указана, используется `NULL ON ERROR`
+3. Если `WRAPPER` секция не указана, используется `WITHOUT WRAPPER`
+4. Если указана секция `WITH WRAPPER`, но не указано `CONDITIONAL` или `UNCONDITIONAL`, используется `UNCONDITIONAL`
+
+**Поведение:**
+
+{% note info %}
+
+Указывать секции `WITH ... WRAPPER` и `ON EMPTY` одновременно нельзя
+
+{% endnote %}
+
+1. Если `<JSON expression>` это `NULL` или пустой `Json?`, то возвращается пустой `Json?`
+2. Если указана `WRAPPER` секция, то:
+ - `WITHOUT WRAPPER` или `WITHOUT ARRAY WRAPPER` - никак не преобразовывать результат выполнения JsonPath
+ - `WITH UNCONDITIONAL WRAPPER` или `WITH UNCONDITIONAL ARRAY WRAPPER` - обернуть результат выполнения JsonPath в массив
+ - `WITH CONDITIONAL WRAPPER` или `WITH CONDITIONAL ARRAY WRAPPER` - обернуть результат выполнения JsonPath в массив если он не является единственным массивом или объектом
+3. Если в результате выполнения JsonPath получился пустой результат, то возвращаемое значение зависит от `ON EMPTY` секции:
+ - `NULL` - вернуть пустой `Json?`
+ - `ERROR` - завершить весь запрос с ошибкой
+ - `EMPTY ARRAY` - вернуть пустой JSON массив, `[]`
+ - `EMPTY OBJECT` - вернуть пустой JSON объект, `{}`
+4. Если возникла ошибка, то возвращаемое значение зависит от `ON ERROR` секции:
+ - `NULL` - вернуть пустой `Json?`
+ - `ERROR` - завершить весь запрос с ошибкой
+ - `EMPTY ARRAY` - вернуть пустой JSON массив, `[]`
+ - `EMPTY OBJECT` - вернуть пустой JSON объект, `{}`
+5. Вернуть полученный результат
+
+Ошибками при выполнении `JSON_QUERY` считаются:
+
+- Ошибки во время вычисления JsonPath
+- Результат выполнения JsonPath - это несколько значений (даже после применения секции `WRAPPER`) или скалярное значение
+
+**Примеры:**
+``` yql
+$json = CAST(@@{
+ "friends": [
+ {
+ "name": "James Holden",
+ "age": 35
+ },
+ {
+ "name": "Naomi Nagata",
+ "age": 30
+ }
+ ]
+}@@ as Json);
+
+SELECT
+ JSON_QUERY($json, "$.friends[0]"); -- {"name": "James Holden", "age": 35}
+
+SELECT
+ JSON_QUERY($json, "$.friends.name" WITH UNCONDITIONAL WRAPPER); -- ["James Holden", "Naomi Nagata"]
+
+SELECT
+ JSON_QUERY($json, "$.friends[0]" WITH CONDITIONAL WRAPPER), -- {"name": "James Holden", "age": 35}
+ JSON_QUERY($json, "$.friends.name" WITH CONDITIONAL WRAPPER); -- ["James Holden", "Naomi Nagata"]
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/list.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/list.md
new file mode 100644
index 00000000000..96b721e13d4
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/list.md
@@ -0,0 +1,542 @@
+# Функции для работы со списками
+
+## ListCreate {#list-create}
+
+Сконструировать пустой список. В единственном аргументе указывается строка с описанием типа данных ячейки списка, либо сам тип, полученный с помощью [предназначенных для этого функций](../types.md). Списков с неизвестным типом ячейки в YQL не бывает.
+
+[Документация по формату описания типа](../../types/type_string.md).
+
+**Примеры**
+``` yql
+SELECT ListCreate(Tuple<String,Double?>);
+```
+
+``` yql
+SELECT ListCreate(OptionalType(DataType("String")));
+```
+
+## AsList и AsListStrict {#aslist}
+
+Сконструировать список из одного или более аргументов. Типы аргументов должны быть совместимы в случае `AsList` и строго совпадать в случае `AsListStrict`.
+
+**Примеры**
+``` yql
+SELECT AsList(1, 2, 3, 4, 5);
+```
+
+## ListLength {#listlength}
+
+Количество элементов в списке.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT ListLength(list_column) FROM my_table;
+```
+{% endif %}
+## ListHasItems
+
+Проверка того, что список содержит хотя бы один элемент.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT ListHasItems(list_column) FROM my_table;
+```
+{% endif %}
+
+## ListCollect {#listcollect}
+
+Преобразовать ленивый список (строится, например, функциями [ListFilter](#listfilter), [ListMap](#listmap), [ListFlatMap](#listflatmap)) в энергичный. В отличие от ленивого списка, в котором каждый повторный проход заново вычисляет его содержимое, в энергичном списке содержимое списка строится сразу ценой большего потребления памяти.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT ListCollect(list_column) FROM my_table;
+```
+{% endif %}
+## ListSort, ListSortAsc и ListSortDesc {#listsort}
+
+Отсортировать список. По умолчанию выполняется сортировка по возрастанию (`ListSort` — алиас к `ListSortAsc`).
+
+Аргументы:
+
+1. Список;
+2. Опциональное выражение для получения ключа сортировки из элемента списка (по умолчанию сам элемент).
+
+**Примеры**
+
+{% if feature_column_container_type %}
+``` yql
+SELECT ListSortDesc(list_column) FROM my_table;
+```
+{% endif %}
+``` yql
+$list = AsList(
+ AsTuple("x", 3),
+ AsTuple("xx", 1),
+ AsTuple("a", 2)
+);
+
+SELECT ListSort($list, ($x) -> {
+ RETURN $x.1;
+});
+```
+
+{% note info %}
+
+В примере использовалась [лямбда функция](../../syntax/expressions.md#lambda).
+
+{% endnote %}
+
+## ListExtend и ListExtendStrict {#listextend}
+
+Последовательно соединить списки (конкатенация списков). В качестве аргументов могут быть списки, опциональные списки и `NULL`.
+Типы элементов списков должны быть совместимы в случае `ListExtend` и строго совпадать в случае `ListExtendStrict`.
+Если хотя бы один из списков является опциональным, то таким же является и результат.
+Если хотя бы один аргумент является `NULL`, то тип результата - `NULL`.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT ListExtend(
+ list_column_1,
+ list_column_2,
+ list_column_3
+) FROM my_table;
+```
+{% endif %}
+
+## ListUnionAll {#listunionall}
+
+Последовательно соединить списки структур (конкатенация списков). В выходном списке структур будет присутствовать поле, если оно есть хотя бы в одном исходном списке, при этом в случае отсутствия такого поля в каком-либо списке оно дополняется как NULL. В случае, когда поле присутствует в двух и более списках, поле в результате приводит в общий тип.
+
+Если хотя бы один из списков является опциональным, то таким же является и результат.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT ListUnionAll(
+ list_column_1,
+ list_column_2,
+ list_column_3
+) FROM my_table;
+```
+{% endif %}
+
+## ListZip и ListZipAll {#listzip}
+
+По входящим спискам построить список пар, содержащих соответствующие по индексу элементы списков (`List<Tuple<first_list_element_type,second_list_element_type>>`).
+
+Длина возвращаемого списка определяется самым коротким списком для ListZip и самым длинным — для ListZipAll.
+Когда более короткий список исчерпан, в качестве пары к элементам более длинного списка подставляется пустое значение (`NULL`) соответствующего [optional типа](../../types/optional.md).
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ListZip(list_column_1, list_column_2, list_column_3),
+ ListZipAll(list_column_1, list_column_2)
+FROM my_table;
+```
+{% endif %}
+
+## ListEnumerate {#listenumerate}
+
+Построить список пар (Tuple), содержащих номер элемента и сам элемент (`List<Tuple<Uint64,list_element_type>>`).
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT ListEnumerate(list_column) FROM my_table;
+```
+{% endif %}
+
+## ListReverse {#listreverse}
+
+Развернуть список.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT ListReverse(list_column) FROM my_table;
+```
+{% endif %}
+
+## ListSkip {#listskip}
+
+Возвращает копию списка с пропущенным указанным числом первых элементов.
+
+Первый аргумент — исходный список, второй — сколько элементов пропустить.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ListSkip(list_column, 3)
+FROM my_table;
+```
+{% endif %}
+
+## ListTake {#listtake}
+
+Возвращает копию списка, состоящую из ограниченного числа элементов второго списка.
+
+Первый аргумент — исходный список, второй — не больше скольких элементов с начала оставить.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT ListTake(list_column, 3) FROM my_table;
+```
+{% endif %}
+
+## ListIndexOf {#listindexof}
+
+Ищет элемент с указанным значением в списке и при первом обнаружении возвращает его индекс. Отсчет индексов начинается с 0, а в случае отсутствия элемента возвращается `NULL`.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ListIndexOf(list_column, 123)
+FROM my_table;
+```
+{% endif %}
+
+## ListMap, ListFlatMap и ListFilter {#listmap}
+
+Применяют к каждому элементу списка указанную в качестве второго аргумента функцию. Различаются возвращаемым результатом:
+
+* `ListMap` — возвращает список с результатами;
+* `ListFlatMap` — возвращает список с результатами, объединяя и разворачивая первый уровень результатов (списков или опциональных значений) по каждому элементу;
+* `ListFilter` — оставляет только те элементы, для которых функция вернула `true`.
+
+{% note info %}
+
+В `ListFlatMap` использование опциональных значений в результатах функции является устаревшим, вместо этого следует использовать комбинацию [`ListNotNull`](#listnotnull) и `ListMap`.
+
+{% endnote %}
+
+Аргументы:
+
+1. Исходный список;
+2. Функции для обработки элементов, например:
+ * [Лямбда функция](../../syntax/expressions.md#lambda);
+ * `Module::Function` - С++ UDF;
+{% if feature_udf_noncpp %}
+ * [Python UDF](../../udf/python.md), [JavaScript UDF](../../udf/javascript.md) или любое другое вызываемое значение;
+
+Если исходный список является опциональным, то таким же является и выходной список.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+$callable = Python::test(Callable<(Int64)->Bool>, "def test(i): return i % 2");
+SELECT
+ ListMap(list_column, ($x) -> { RETURN $x > 2; }),
+ ListFlatMap(list_column, My::Udf),
+ ListFilter(list_column, $callable)
+FROM my_table;
+```
+{% endif %}
+{% endif %}
+
+## ListNotNull {#listnotnull}
+
+Применяет трансформацию исходного списка, пропуская пустые опциональные элементы, и усиливает тип элемента до неопционального. Для списка с неопциональными элементами возвращает исходный список без изменений.
+
+Если исходный список является опциональным, то таким же является и выходной список.
+
+**Примеры**
+``` yql
+SELECT ListNotNull([1,2]), -- [1,2]
+ ListNotNull([3,null,4]); -- [3,4]
+```
+
+## ListFlatten {#listflatten}
+
+Разворачивает список списков в плоский список с сохранением порядка элементов. В качестве элемента списка верхнего уровня поддерживается опциональный список, который интерпретируется как пустой в случае `NULL`.
+
+Если исходный список является опциональным, то таким же является и выходной список.
+
+**Примеры**
+``` yql
+SELECT ListFlatten([[1,2],[3,4]]), -- [1,2,3,4]
+ ListFlatten([null,[3,4],[5,6]]); -- [3,4,5,6]
+```
+
+## ListUniq {#listuniq}
+
+Возвращает копию списка, в котором оставлен только уникальный набор элементов.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ListUniq(list_column)
+FROM my_table;
+```
+{% endif %}
+
+## ListAny и ListAll {#listany}
+
+Для списка булевых значений возвращает `true`, если:
+
+* `ListAny` — хотя бы один элемент равен `true`;
+* `ListAll` — все элементы равны `true`.
+
+В противном случае возвращает false.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ListAll(bool_column),
+ ListAny(bool_column)
+FROM my_table;
+```
+{% endif %}
+
+## ListHas {#listhas}
+
+Содержит ли список указанный элемент.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ListHas(list_column, "my_needle")
+FROM my_table;
+```
+{% endif %}
+
+## ListHead, ListLast {#listheadlast}
+
+Возвращают первый и последний элемент списка.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ListHead(numeric_list_column) AS head,
+ ListLast(numeric_list_column) AS last
+FROM my_table;
+```
+{% endif %}
+
+## ListMin, ListMax, ListSum и ListAvg {#listminy}
+
+Применяет соответствующую агрегатную функцию ко всем элементам списка числовых значений.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ListMax(numeric_list_column) AS max,
+ ListMin(numeric_list_column) AS min,
+ ListSum(numeric_list_column) AS sum,
+ ListAvg(numeric_list_column) AS avg
+FROM my_table;
+```
+{% endif %}
+
+## ListFold, ListFold1 {#listfold}
+
+Свёртка списка.
+
+Аргументы:
+
+1. Список
+2. Начальное состояние U для ListFold, initLambda(item:T)->U для ListFold1
+3. updateLambda(item:T, state:U)->U
+
+Возвращаемый тип:
+U для ListFold, опциональный U для ListFold1.
+
+**Примеры**
+
+```yql
+$l = [1, 4, 7, 2];
+$y = ($x, $y) -> { RETURN $x + $y; };
+$z = ($x) -> { RETURN 4 * $x; };
+
+SELECT
+ ListFold($l, 6, $y) AS fold, -- 20
+ ListFold([], 3, $y) AS fold_empty, -- 3
+ ListFold1($l, $z, $y) AS fold1, -- 17
+ ListFold1([], $z, $y) AS fold1_empty; -- Null
+```
+
+## ListFoldMap, ListFold1Map {#listfoldmap}
+
+Преобразует каждый элемент i в списке путём вызова handler(i, state).
+
+Аргументы:
+
+1. Список
+2. Начальное состояние S для ListFoldMap, initLambda(item:T)->кортеж (U S) для ListFold1Map
+3. handler(item:T, state:S)->кортеж (U S)
+
+Возвращаемый тип:
+Список элементов U.
+
+**Примеры**
+
+```yql
+$l = [1, 4, 7, 2];
+$x = ($i, $s) -> { RETURN ($i * $s, $i + $s); };
+$t = ($i) -> { RETURN ($i + 1, $i + 2); };
+
+SELECT
+ ListFoldMap([], 1, $x), -- []
+ ListFoldMap($l, 1, $x), -- [1, 8, 42, 26]
+ ListFold1Map([], $t, $x), -- []
+ ListFold1Map($l, $t, $x); -- [2, 12, 49, 28]
+```
+
+## ListFromRange {#listfromrange}
+
+Генерация последовательности чисел с указанным шагом. Аналог `xrange` в Python 2, но дополнительно с поддержкой чисел с плавающей точкой.
+
+Аргументы:
+
+1. Начало
+2. Конец
+3. Шаг (опционально, по умолчанию 1)
+
+Особенности:
+
+* Конец не включительный, т.е. `ListFromRange(1,3) == AsList(1,2)`.
+* Тип элементов результатов выбирается как наиболее широкий из типов аргументов, например результатом `ListFromRange(1, 2, 0.5)` получится список `Double`.
+* Список является «ленивым», но при неправильном использовании всё равно может привести к потреблению большого объема оперативной памяти.
+* Если шаг положительный и конец меньше или равен началу, то список будет пустой.
+* Если шаг отрицательный и конец больше или равен началу, то список будет пустой.
+* Если шаг не положительный и не отрицательный (0 или NaN), то список будет пустой.
+
+**Примеры**
+``` yql
+SELECT
+ ListFromRange(-2, 2), -- [-2, -1, 0, 1]
+ ListFromRange(2, 1, -0.5); -- [2.0, 1.5]
+```
+
+## ListReplicate {#listreplicate}
+
+Создает список из нескольких копий указанного значения.
+
+Обязательные аргументы:
+
+1. Значение;
+2. Число копий.
+
+**Примеры**
+``` yql
+SELECT ListReplicate(true, 3); -- [true, true, true]
+```
+
+## ListConcat {#listconcat}
+
+Объединяет список строк в одну строку.
+Вторым параметром можно задать разделитель.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ListConcat(string_list_column),
+ ListConcat(string_list_column, "; ")
+FROM my_table;
+```
+{% endif %}
+
+## ListExtract {#listextract}
+
+По списку структур возвращает список содержащихся в них полей с указанным именем.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ListExtract(struct_list_column, "MyMember")
+FROM my_table;
+```
+{% endif %}
+
+## ListTakeWhile, ListSkipWhile {#listtakewhile}
+
+`ListTakeWhile` выдает список от начала, пока предикат истинный, далее список заканчивается.
+
+`ListSkipWhile` пропускает отрезок списка от начала, пока предикат истинный, далее выдает остаток список не обращая внимания на предикат.
+`ListTakeWhileInclusive` выдает список от начала, пока предикат истинный, далее список заканчивается, но также включает элемент, на котором сработал останавливающий предикат.
+`ListSkipWhileInclusive` пропускает отрезок списка от начала, пока предикат истинный, далее выдает остаток список не обращая внимания на предикат, но не включая элемент, на котором сработал предикат, а начинает со следующего за ним.
+
+Обязательные аргументы:
+
+1. Список;
+2. Предикат.
+
+Если входной список является опциональным, то таким же является и результат.
+
+**Примеры**
+``` yql
+$data = AsList(1, 2, 5, 1, 2, 7);
+
+SELECT
+ ListTakeWhile($data, ($x) -> {return $x <= 3}), -- [1, 2]
+ ListSkipWhile($data, ($x) -> {return $x <= 3}), -- [5, 1, 2, 7]
+ ListTakeWhileInclusive($data, ($x) -> {return $x <= 3}), -- [1, 2, 5]
+ ListSkipWhileInclusive($data, ($x) -> {return $x <= 3}); -- [1, 2, 7]
+```
+
+## ListAggregate {#listaggregate}
+
+Применить [фабрику агрегационных функций](../basic.md#aggregationfactory) для переданного списка.
+Если переданный список является пустым, то результат агрегации будет такой же, как для пустой таблицы: 0 для функции `COUNT` и `NULL` для других функций.
+Если переданный список является опциональным и равен `NULL`, то в результате также будет `NULL`.
+
+Аргументы:
+
+1. Список;
+2. [Фабрика агрегационных функций](../basic.md#aggregationfactory).
+
+
+**Примеры**
+``` yql
+SELECT ListAggregate(AsList(1, 2, 3), AggregationFactory("Sum")); -- 6
+```
+
+## ToDict и ToMultiDict {#todict}
+
+Преобразуют список из кортежей с парами ключ-значение в словарь. В случае конфликтов по ключам во входном списке `ToDict` оставляет первое значение, а `ToMultiDict` — собирает из всех значений список.
+
+Таким образом:
+
+* `ToDict` из `List<Tuple<K, V>>` делает `Dict<K, V>`
+* `ToMultiDict` из `List<Tuple<K, V>>` делает `Dict<K, List<V>>`
+
+Также поддерживаются опциональные списки, что приводит к опциональному словарю в результате.
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ToDict(tuple_list_column)
+FROM my_table;
+```
+{% endif %}
+
+## ToSet {#toset}
+Преобразует список в словарь, в котором ключи являются уникальными элементами этого списка, а значения отсутствуют и имеют тип `Void`. Для списка `List<T>` тип результата будет `Dict<T, Void>`.
+Также поддерживается опциональный список, что приводит к опциональному словарю в результате.
+
+Обратная функция - получить список ключей словаря [DictKeys](../dict.md#dictkeys).
+
+**Примеры**
+{% if feature_column_container_type %}
+``` yql
+SELECT
+ ToSet(list_column)
+FROM my_table;
+```
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/struct.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/struct.md
new file mode 100644
index 00000000000..8b8f5de6912
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/struct.md
@@ -0,0 +1,304 @@
+# Функции для работы со структурами
+
+## TryMember {#trymember}
+
+Попытка получить поле из структуры, а в случае его отсутствия среди полей или null в значении структуры использовать значение по умолчанию.
+
+Аргументы:
+
+1. Структура;
+2. Имя поля;
+3. Значение по умолчанию.
+
+``` yql
+$struct = <|a:1|>;
+SELECT
+ TryMember(
+ $struct,
+ "a",
+ 123
+ ) AS a, -- 1
+ TryMember(
+ $struct,
+ "b",
+ 123
+ ) AS b; -- 123
+```
+
+## ExpandStruct {#expandstruct}
+
+Добавление одного или нескольких новых полей в структуру.
+
+В случае возникновения дублей в наборе полей будет возвращена ошибка.
+
+Аргументы:
+
+* В первый аргумент передается исходная структура для расширения.
+* Все остальные аргументы должны быть именованными, каждый аргумент добавляет новое поле и имя аргумента используется в роли имени поля (по аналогии с [AsStruct](../basic.md#asstruct)).
+
+**Примеры**
+``` yql
+$struct = <|a:1|>;
+SELECT
+ ExpandStruct(
+ $struct,
+ 2 AS b,
+ "3" AS c
+ ) AS abc;
+```
+
+## AddMember {#addmember}
+
+Добавление одного нового поля в структуру. Если необходимо добавление нескольких полей, предпочтительнее использовать [ExpandStruct](#expandstruct).
+
+В случае возникновения дублей в наборе полей будет возвращена ошибка.
+
+Аргументы:
+
+1. Исходная структура;
+2. Имя нового поля;
+3. Значение нового поля.
+
+**Примеры**
+``` yql
+$struct = <|a:1|>;
+SELECT
+ AddMember(
+ $struct,
+ "b",
+ 2
+ ) AS ab;
+```
+
+## RemoveMember {#removemember}
+
+Удаление поля из структуры.
+
+Если указанного поля не существовало, будет возвращена ошибка.
+
+Аргументы:
+
+1. Исходная структура;
+2. Имя поля.
+
+**Примеры**
+``` yql
+$struct = <|a:1, b:2|>;
+SELECT
+ RemoveMember(
+ $struct,
+ "b"
+ ) AS a;
+```
+
+## ForceRemoveMember {#forceremovemember}
+
+Удаление поля из структуры.
+
+Если указанного поля не существовало, в отличии от [RemoveMember](#removemember) ошибка возвращена не будет.
+
+Аргументы:
+
+1. Исходная структура;
+2. Имя поля.
+
+**Примеры**
+``` yql
+$struct = <|a:1, b:2|>;
+SELECT
+ ForceRemoveMember(
+ $struct,
+ "c"
+ ) AS ab;
+```
+
+## ChooseMembers {#choosemembers}
+
+Выделение из структуры полей с заданными именами.
+
+Если какого-либо из полей не существовало, будет возвращена ошибка.
+
+Аргументы:
+
+1. Исходная структура;
+2. Список имен полей.
+
+**Примеры**
+``` yql
+$struct = <|a:1, b:2, c:3|>;
+SELECT
+ ChooseMembers(
+ $struct,
+ ["a", "b"]
+ ) AS ab;
+```
+
+## RemoveMembers {#removemembers}
+
+Исключение из структуры полей с заданными именами.
+
+Если какого-либо из полей не существовало, будет возвращена ошибка.
+
+Аргументы:
+
+1. Исходная структура;
+2. Список имен полей.
+
+**Примеры**
+``` yql
+$struct = <|a:1, b:2, c:3|>;
+SELECT
+ RemoveMembers(
+ $struct,
+ ["a", "b"]
+ ) AS c;
+```
+
+## ForceRemoveMembers {#forceremovemembers}
+
+Исключение из структуры полей с заданными именами.
+
+Если какого-либо из полей не существовало, то оно игнорируется.
+
+Аргументы:
+
+1. Исходная структура;
+2. Список имен полей.
+
+**Примеры**
+``` yql
+$struct = <|a:1, b:2, c:3|>;
+SELECT
+ ForceRemoveMembers(
+ $struct,
+ ["a", "b", "z"]
+ ) AS c;
+```
+
+## CombineMembers {#combinemembers}
+
+Объединение полей нескольких структур в новую структуру.
+
+В случае возникновения дублей в результирующем наборе полей будет возвращена ошибка.
+
+Аргументы: две и более структуры.
+
+**Примеры**
+``` yql
+$struct1 = <|a:1, b:2|>;
+$struct2 = <|c:3|>;
+SELECT
+ CombineMembers(
+ $struct1,
+ $struct2
+ ) AS abc;
+```
+
+## FlattenMembers {#flattenmembers}
+
+Объединение полей нескольких новых структур в новую структуру с поддержкой префиксов.
+
+В случае возникновения дублей в результирующем наборе полей будет возвращена ошибка.
+
+Аргументы: два и более кортежа из двух элементов: префикс и структура.
+
+**Примеры**
+``` yql
+$struct1 = <|a:1, b:2|>;
+$struct2 = <|c:3|>;
+SELECT
+ FlattenMembers(
+ AsTuple("foo", $struct1), -- fooa, foob
+ AsTuple("bar", $struct2) -- barc
+ ) AS abc;
+```
+
+## StructMembers {#structmembers}
+
+Возвращает неупорядоченный список имен полей (возможно, сняв один уровень опциональности) для единственного аргумента - структуры. Для `NULL` аргумента возвращается пустой список строк.
+
+Аргумент: структура
+
+**Примеры**
+``` yql
+$struct = <|a:1, b:2|>;
+SELECT
+ StructMembers($struct); -- ['a', 'b']
+```
+
+## RenameMembers {#renamemembers}
+
+Переименовывает поля в переданной структуре. При этом исходное поле можно переименовать в несколько новых. Все поля, не упомянутые в переименовании как исходные, переносятся в результирующую структуру. Если нет какого-то исходного поля в списке для переименования, выдается ошибка. Для опциональной структуры либо `NULL` таким же является и результат.
+
+Аргументы:
+
+1. Исходная структура;
+2. Список имен полей в форме списка таплов: исходное имя, новое имя.
+
+**Примеры**
+``` yql
+$struct = <|a:1, b:2|>;
+SELECT
+ RenameMembers($struct, [('a', 'c'), ('a', 'e')]); -- (b:2, c:1, e:1)
+```
+
+## ForceRenameMembers {#forecerenamemembers}
+
+Переименовывает поля в переданной структуре. При этом исходное поле можно переименовать в несколько новых. Все поля, не упомянутые в переименовании как исходные, переносятся в результирующую структуру. Если нет какого-то исходного поля в списке для переименования, оно игнорируется. Для опциональной структуры либо `NULL` таким же является и результат.
+
+Аргументы:
+
+1. Исходная структура;
+2. Список имен полей в форме списка таплов: исходное имя, новое имя.
+
+**Примеры**
+``` yql
+$struct = <|a:1, b:2|>;
+SELECT
+ ForceRenameMembers($struct, [('a', 'c'), ('d', 'e')]); -- (b:2, c:1)
+```
+
+## GatherMembers {#gathermembers}
+
+Возвращает неупорядоченный список таплов из имени поля и значения. Для `NULL` аргумента возвращается `EmptyList`. Можно использовать только в тех случаях, когда типы элементов в структуре одинаковы или совместимы. Для опциональной структуры возвращает опциональный список.
+
+Аргумент: структура
+
+**Примеры**
+``` yql
+$struct = <|a:1, b:2|>;
+SELECT
+ GatherMembers($struct); -- [('a', 1), ('b', 2)]
+```
+
+## SpreadMembers {#spreadmembers}
+
+Создает структуру с заданным списком полей и применяет к ней заданный список исправлений в формате (имя поля, значение). Все типы полей результирующей структуры совпадают, и равны типу значений в списке исправлений с добавленной опциональностью (если еще не были таковыми). Если поле не было упомянуто среди списка редактируемых полей, оно возвращается как `NULL`. Среди всех исправлений по одному полю сохраняется последнее. Если список исправлений опционален либо равен `NULL`, то таковым является и результат. Если в списке исправлений встречается поле, которого нет в списке ожидаемых полей, выдается ошибка.
+
+Аргументы:
+
+1. Список таплов: имя поля, значение поля;
+2. Список всех возможных имен полей в структуре.
+
+**Примеры**
+``` yql
+
+SELECT
+ SpreadMembers([('a',1),('a',2)],['a','b']); -- (a: 2, b: null)
+```
+
+## ForceSpreadMembers {#forcespreadmembers}
+
+Создает структуру с заданным списком полей и применяет к ней заданный список исправлений в формате (имя поля, значение). Все типы полей результирующей структуры совпадают, и равны типу значений в списке исправлений с добавленной опциональностью (если еще не были таковыми). Если поле не было упомянуто среди списка редактируемых полей, оно возвращается как `NULL`. Среди всех исправлений по одному полю сохраняется последнее. Если список исправлений опционален либо равен `NULL`, то таковым является и результат. Если в списке исправлений встречается поле, которого нет в списке ожидаемых полей, то это исправление игнорируется.
+
+Аргументы:
+
+1. Список таплов: имя поля, значение поля;
+2. Список всех возможных имен полей в структуре.
+
+**Примеры**
+``` yql
+
+SELECT
+ ForceSpreadMembers([('a',1),('a',2),('c',100)],['a','b']); -- (a: 2, b: null)
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/types.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/types.md
new file mode 100644
index 00000000000..cf557a8e196
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/types.md
@@ -0,0 +1,579 @@
+# Функции для работы с типами данных
+
+## FormatType {#formattype}
+
+Сериализация типа {% if feature_codegen %} или хендла типа{% endif %} в человекочитаемую строку. Это полезно для отладки, а также будет использоваться в последующих примерах данного раздела. [Документация по формату](../../types/type_string.md).
+
+## ParseType {#parsetype}
+
+Построение типа по строке с его описанием. [Документация по её формату](../../types/type_string.md).
+
+**Примеры**
+``` yql
+SELECT FormatType(ParseType("List<Int32>")); -- List<int32>
+```
+
+## TypeOf {#typeof}
+
+Получение типа значения, переданного в аргумент.
+
+**Примеры**
+``` yql
+SELECT FormatType(TypeOf("foo")); -- String
+```
+``` yql
+SELECT FormatType(TypeOf(AsTuple(1, 1u))); -- Tuple<Int32,Uint32>
+```
+
+## InstanceOf {#instanceof}
+
+Возвращает экземпляр указанного типа, который можно использовать только для получения типа результата выражения с его использованием.
+
+Если этот экземпляр останется в графе вычислений к моменту окончания оптимизации, то операция будет завершена с ошибкой.
+
+**Примеры**
+``` yql
+SELECT FormatType(TypeOf(
+ InstanceOf(ParseType("Int32")) +
+ InstanceOf(ParseType("Double"))
+)); -- Double, так как "Int32 + Double" возвращает Double
+```
+
+## DataType {#datatype}
+
+Возвращает тип для [примитивных типов данных](../../types/primitive.md) по его имени.
+
+**Примеры**
+``` yql
+SELECT FormatType(DataType("Bool")); -- Bool
+SELECT FormatType(DataType("Decimal","5","1")); -- Decimal(5,1)
+```
+
+## OptionalType {#optionaltype}
+
+Добавляет в переданный тип возможность содержать `NULL`.
+
+**Примеры**
+``` yql
+SELECT FormatType(OptionalType(DataType("Bool"))); -- Bool?
+```
+
+## ListType и StreamType {#listtype}
+
+Строит тип списка или потока по переданному типу элемента.
+
+**Примеры**
+``` yql
+SELECT FormatType(ListType(DataType("Bool"))); -- List<Bool>
+```
+
+## DictType {#dicttype}
+
+Строит тип словаря по переданным типам ключа (первый аргумент) и значения (второй аргумент).
+
+**Примеры**
+``` yql
+SELECT FormatType(DictType(
+ DataType("String"),
+ DataType("Double")
+)); -- Dict<String,Double>
+```
+
+## TupleType {#tupletype}
+
+Строит тип кортежа по переданным типам элементов.
+
+**Примеры**
+``` yql
+SELECT FormatType(TupleType(
+ DataType("String"),
+ DataType("Double"),
+ OptionalType(DataType("Bool"))
+)); -- Tuple<String,Double,Bool?>
+```
+
+## StructType {#structtype}
+
+Строит тип структуры по переданным типам элементов. Для указания имен элементов используется стандартный синтаксис именованных аргументов.
+
+**Примеры**
+``` yql
+SELECT FormatType(StructType(
+ DataType("Bool") AS MyBool,
+ ListType(DataType("String")) AS StringList
+)); -- Struct<'MyBool':Bool,'StringList':List<String>>
+```
+
+## VariantType {#varianttype}
+
+Возвращает тип варианта по низлежащему типу (структуры или кортежа).
+
+**Примеры**
+``` yql
+SELECT FormatType(VariantType(
+ ParseType("Struct<foo:Int32,bar:Double>")
+)); -- Variant<'bar':Double,'foo':Int32>
+```
+
+## ResourceType {#resourcetype}
+
+Возвращает тип [ресурса](../../types/special.md) по переданной строковой метке.
+
+**Примеры**
+``` yql
+SELECT FormatType(ResourceType("Foo")); -- Resource<'Foo'>
+```
+
+## CallableType {#callabletype}
+
+Строит тип вызываемого значения по следующим аргументам:
+
+1. Число опциональных аргументов (если все обязательные — 0).
+2. Тип результата.
+3. Все последующие аргументы CallableType трактуются как типы аргументов вызываемого значения со сдвигом на два обязательных (например, третий аргумент CallableType описывает тип первого аргумента вызываемого значения).
+
+**Примеры**
+``` yql
+SELECT FormatType(CallableType(
+ 1, -- optional args count
+ DataType("Double"), -- result type
+ DataType("String"), -- arg #1 type
+ OptionalType(DataType("Int64")) -- arg #2 type
+)); -- Callable<(String,[Int64?])->Double>
+```
+
+## GenericType, UnitType и VoidType {#generictype}
+
+Возвращают одноименные [специальные типы данных](../../types/special.md). Аргументов нет, так как они не параметризуются.
+
+**Примеры**
+``` yql
+SELECT FormatType(VoidType()); -- Void
+```
+
+## OptionalItemType, ListItemType и StreamItemType {#optionalitemtype}
+
+{% if feature_codegen %} Если этим функциям передается тип, то они выполняют{% else %}Выполняют{% endif %} действие, обратное [OptionalType](#optionaltype), [ListType](#listtype) и [StreamType](#streamtype) — возвращают тип элемента по типу соответствующего контейнера.
+{% if feature_codegen %}
+Если этим функциям передается хендл типа, то выполняют действие, обратное [OptionalTypeHandle](#optionaltypehandle), [ListTypeHandle](#listtypehandle) и [StreamTypeHandle](#streamtypehandle) - возвращают хендл типа элемента по хендлу типа соответствующего контейнера.
+{% endif %}
+
+**Примеры**
+``` yql
+SELECT FormatType(ListItemType(
+ ParseType("List<Int32>")
+)); -- Int32
+```
+{% if feature_codegen %}
+``` yql
+SELECT FormatType(ListItemType(
+ ParseTypeHandle("List<Int32>")
+)); -- Int32
+```
+{% endif %}
+
+## DictKeyType и DictPayloadType {#dictkeytype}
+
+Возвращают тип ключа или значения по типу словаря.
+
+**Примеры**
+``` yql
+SELECT FormatType(DictKeyType(
+ ParseType("Dict<Int32,String>")
+)); -- Int32
+```
+
+## TupleElementType {#tupleelementtype}
+
+Возвращает тип элемента кортежа по типу кортежа и индексу элемента (индекс с нуля).
+
+**Примеры**
+``` yql
+SELECT FormatType(TupleElementType(
+ ParseType("Tuple<Int32,Double>"), "1"
+)); -- Double
+```
+
+## StructMemberType {#structmembertype}
+
+Возвращает тип элемента структуры по типу структуры и имени элемента.
+
+**Примеры**
+``` yql
+SELECT FormatType(StructMemberType(
+ ParseType("Struct<foo:Int32,bar:Double>"), "foo"
+)); -- Int32
+```
+
+## CallableResultType и CallableArgumentType {#callableresulttype}
+
+`CallableResultType` возвращает тип результата по типу вызываемого значения, а `CallableArgumentType` — тип аргумента по типу вызываемого значения и его индексу (индекс с нуля).
+
+**Примеры**
+``` yql
+$callable_type = ParseType("(String,Bool)->Double");
+
+SELECT FormatType(CallableResultType(
+ $callable_type
+)), -- Double
+FormatType(CallableArgumentType(
+ $callable_type, 1
+)); -- Bool
+```
+
+## VariantUnderlyingType {#variantunderlyingtype}
+
+{% if feature_codegen %}Если этой функции передается тип, то она выполняет{% else %}Выполняет{% endif %} действие, обратное [VariantType](#varianttype) — возвращает низлежащий тип по типу варианта.
+{% if feature_codegen %}
+Если этой функции передается хендл типа, то она выполняет действие, обратное [VariantTypeHandle](#varianttypehandle) — возвращает хендл низлежащего типа по хендлу типа варианта.
+{% endif %}
+
+**Примеры**
+``` yql
+SELECT FormatType(VariantUnderlyingType(
+ ParseType("Variant<foo:Int32,bar:Double>")
+)), -- Struct<'bar':Double,'foo':Int32>
+FormatType(VariantUnderlyingType(
+ ParseType("Variant<Int32,Double>")
+)); -- Tuple<Int32,Double>
+```
+{% if feature_codegen %}
+``` yql
+SELECT FormatType(VariantUnderlyingType(
+ ParseTypeHandle("Variant<foo:Int32,bar:Double>")
+)), -- Struct<'bar':Double,'foo':Int32>
+FormatType(VariantUnderlyingType(
+ ParseTypeHandle("Variant<Int32,Double>")
+)); -- Tuple<Int32,Double>
+```
+{% endif %}
+
+{% if feature_codegen %}
+# Функции для работы с типами данных во время выполнения вычислений
+
+Для работы с типами данных во время выполнения вычислений используется механизм хендлов типов - [ресурс](../../types/special.md), содержащий непрозрачное описание типа. После конструирования хендла типа можно вернуться к обычному типу с помощью функции [EvaluateType](#evaluatetype). Для отладки сконвертировать хендл типа в строку можно с помощью функции [FormatType](#formattype).
+
+## TypeHandle
+
+Получение хендла типа из типа, переданного в аргумент.
+
+**Примеры:**
+``` yql
+SELECT FormatType(TypeHandle(TypeOf("foo"))); -- String
+```
+## EvaluateType
+
+Получение типа из хендла типа, переданного в аргумент. Функция вычисляется до начала основного расчета, как и [EvaluateExpr](../basic.md#evaluate_expr_atom).
+
+**Примеры:**
+``` yql
+SELECT FormatType(EvaluateType(TypeHandle(TypeOf("foo")))); -- String
+```
+
+## ParseTypeHandle
+
+Построение хендла типа по строке с его описанием. [Документация по её формату](../../types/type_string.md).
+
+**Примеры:**
+``` yql
+SELECT FormatType(ParseTypeHandle("List<Int32>")); -- List<int32>
+```
+
+## TypeKind
+
+Получение названия верхнего уровня типа из хендла типа, переданного в аргумент.
+
+**Примеры:**
+``` yql
+SELECT TypeKind(TypeHandle(TypeOf("foo"))); -- Data
+SELECT TypeKind(ParseTypeHandle("List<Int32>")); -- List
+```
+
+## DataTypeComponents
+
+Получение названия и параметров [примитивного типа данных](../../types/primitive.md) из хендла примитивного типа, переданного в аргумент. Обратная функция - [DataTypeHandle](#datatypehandle).
+
+**Примеры:**
+``` yql
+SELECT DataTypeComponents(TypeHandle(TypeOf("foo"))); -- ["String"]
+SELECT DataTypeComponents(ParseTypeHandle("Decimal(4,1)")); -- ["Decimal", "4", "1"]
+```
+
+## DataTypeHandle
+
+Построение хендла [примитивного типа данных](../../types/primitive.md) из его названия и параметров, переданных списком в аргумент. Обратная функция - [DataTypeComponents](#datatypecomponents).
+
+**Примеры:**
+``` yql
+SELECT FormatType(DataTypeHandle(
+ AsList("String")
+)); -- String
+
+SELECT FormatType(DataTypeHandle(
+ AsList("Decimal", "4", "1")
+)); -- Decimal(4,1)
+```
+
+## OptionalTypeHandle
+
+Добавляет в переданный хендл типа возможность содержать `NULL`.
+
+**Примеры:**
+``` yql
+SELECT FormatType(OptionalTypeHandle(
+ TypeHandle(DataType("Bool"))
+)); -- Bool?
+```
+
+## ListTypeHandle и StreamTypeHandle {#list-stream-typehandle}
+
+Строит хендл типа списка или потока по переданному хендлу типа элемента.
+
+**Примеры:**
+``` yql
+SELECT FormatType(ListTypeHandle(
+ TypeHandle(DataType("Bool"))
+)); -- List<Bool>
+```
+
+## EmptyListTypeHandle и EmptyDictTypeHandle
+
+Строит хендл типа пустого списка или словаря.
+
+**Примеры:**
+``` yql
+SELECT FormatType(EmptyListTypeHandle()); -- EmptyList
+```
+
+## TupleTypeComponents
+
+Получение списка хендлов типов элементов из хендла типа кортежа, переданного в аргумент. Обратная функция - [TupleTypeHandle](#tupletypehandle).
+
+**Примеры:**
+``` yql
+SELECT ListMap(
+ TupleTypeComponents(
+ ParseTypeHandle("Tuple<Int32, String>")
+ ),
+ ($x)->{
+ return FormatType($x)
+ }
+); -- ["Int32", "String"]
+```
+
+## TupleTypeHandle
+
+Построение хендла типа кортежа из хендлов типов элементов, переданных списком в аргумент. Обратная функция - [TupleTypeComponents](#tupletypecomponents).
+
+**Примеры:**
+``` yql
+SELECT FormatType(
+ TupleTypeHandle(
+ AsList(
+ ParseTypeHandle("Int32"),
+ ParseTypeHandle("String")
+ )
+ )
+); -- Tuple<Int32,String>
+```
+
+## StructTypeComponents
+
+Получение списка хендлов типов элементов и их имен из хендла типа структуры, переданного в аргумент. Обратная функция - [StructTypeHandle](#structtypehandle).
+
+**Примеры:**
+``` yql
+SELECT ListMap(
+ StructTypeComponents(
+ ParseTypeHandle("Struct<a:Int32, b:String>")
+ ),
+ ($x) -> {
+ return AsTuple(
+ FormatType($x.Type),
+ $x.Name
+ )
+ }
+); -- [("Int32","a"), ("String","b")]
+```
+
+## StructTypeHandle
+
+Построение хендла типа структуры из хендлов типов элементов и имен, переданных списком в аргумент. Обратная функция - [StructTypeComponents](#structtypecomponents).
+
+**Примеры:**
+``` yql
+SELECT FormatType(
+ StructTypeHandle(
+ AsList(
+ AsStruct(ParseTypeHandle("Int32") as Type,"a" as Name),
+ AsStruct(ParseTypeHandle("String") as Type, "b" as Name)
+ )
+ )
+); -- Struct<'a':Int32,'b':String>
+```
+
+## DictTypeComponents
+
+Получение хендла типа-ключа и хендла типа-значения - из хендла типа словаря, переданного в аргумент. Обратная функция - [DictTypeHandle](#dicttypehandle).
+
+**Примеры:**
+``` yql
+$d = DictTypeComponents(ParseTypeHandle("Dict<Int32,String>"));
+
+SELECT
+ FormatType($d.Key), -- Int32
+ FormatType($d.Payload); -- String
+```
+
+## DictTypeHandle
+
+Построение хендла типа словаря из хендла типа-ключа и хендла типа-значения, переданных в аргументы. Обратная функция - [DictTypeComponents](#dicttypecomponents).
+
+**Примеры:**
+``` yql
+SELECT FormatType(
+ DictTypeHandle(
+ ParseTypeHandle("Int32"),
+ ParseTypeHandle("String")
+ )
+); -- Dict<Int32, String>
+```
+
+## ResourceTypeTag
+
+Получение тега из хендла типа ресурса, переданного в аргумент. Обратная функция - [ResourceTypeHandle](#resourcetypehandle).
+
+**Примеры:**
+``` yql
+SELECT ResourceTypeTag(ParseTypeHandle("Resource<foo>")); -- foo
+```
+
+## ResourceTypeHandle
+
+Построение хендла типа ресурса по значению тега, переданного в аргумент. Обратная функция - [ResourceTypeTag](#resourcetypetag).
+
+**Примеры:**
+``` yql
+SELECT FormatType(ResourceTypeHandle("foo")); -- Resource<'foo'>
+```
+
+## TaggedTypeComponents
+
+Получение тега и базового типа из хендла декорированного типа, переданного в аргумент. Обратная функция - [TaggedTypeHandle](#taggedtypehandle).
+
+**Примеры:**
+``` yql
+$t = TaggedTypeComponents(ParseTypeHandle("Tagged<Int32,foo>"));
+
+SELECT FormatType($t.Base), $t.Tag; -- Int32, foo
+```
+
+## TaggedTypeHandle
+
+Построение хендла декорированного типа по хендлу базового типа и имени тега, переданных в аргументах. Обратная функция - [TaggedTypeComponents](#taggedtypecomponents).
+
+**Примеры:**
+``` yql
+SELECT FormatType(TaggedTypeHandle(
+ ParseTypeHandle("Int32"), "foo"
+)); -- Tagged<Int32, 'foo'>
+```
+
+## VariantTypeHandle
+
+Построение хендла типа варианта по хендлу низлежащего типа, переданного в аргумент. Обратная функция - [VariantUnderlyingType](#variantunderlyingtype).
+
+**Примеры:**
+``` yql
+SELECT FormatType(VariantTypeHandle(
+ ParseTypeHandle("Tuple<Int32, String>")
+)); -- Variant<Int32, String>
+```
+
+## VoidTypeHandle и NullTypeHandle
+
+Построение хендла типов Void и Null соответственно.
+
+**Примеры:**
+``` yql
+SELECT FormatType(VoidTypeHandle()); -- Void
+SELECT FormatType(NullTypeHandle()); -- Null
+```
+
+## CallableTypeComponents
+
+Получение описания хендла типа вызываемого значения, переданного в аргумент. Обратная функция - [CallableTypeHandle](#callabletypehandle).
+
+**Примеры:**
+``` yql
+$formatArgument = ($x) -> {
+ return AsStruct(
+ FormatType($x.Type) as Type,
+ $x.Name as Name,
+ $x.Flags as Flags
+ )
+};
+
+$formatCallable = ($x) -> {
+ return AsStruct(
+ $x.OptionalArgumentsCount as OptionalArgumentsCount,
+ $x.Payload as Payload,
+ FormatType($x.Result) as Result,
+ ListMap($x.Arguments, $formatArgument) as Arguments
+ )
+};
+
+SELECT $formatCallable(
+ CallableTypeComponents(
+ ParseTypeHandle("(Int32,[bar:Double?{Flags:AutoMap}])->String")
+ )
+); -- (OptionalArgumentsCount: 1, Payload: "", Result: "String", Arguments: [
+ -- (Type: "Int32", Name: "", Flags: []),
+ -- (Type: "Double?", Name: "bar", Flags: ["AutoMap"]),
+ -- ])
+```
+
+## CallableArgument
+
+Упаковка в структуру описания аргумента вызываемого значения для передачи в функцию [CallableTypeHandle](#callabletypehandle) по следующим аргументам:
+
+1. Хендл типа аргумента.
+2. Необязательное имя аргумента. Значение по умолчанию - пустая строка.
+3. Необязательные флаги аргумента в виде списка строк. Значение по умолчанию - пустой список. Поддерживаемые флаги - "AutoMap".
+
+## CallableTypeHandle
+
+Построение хендла типа вызываемого значения по следующим аргументам:
+
+1. Хендл типа возвращаемого значения.
+2. Список описаний аргументов, полученных через функцию [CallableArgument](#callableargument).
+3. Необязательное количество необязательных аргументов в вызываемом значении. Значение по умолчанию - 0.
+4. Необязательная метка для типа вызываемого значения. Значение по умолчанию - пустая строка.
+
+Обратная функция - [CallableTypeComponents](#callabletypecomponents).
+
+**Примеры:**
+``` yql
+SELECT FormatType(
+ CallableTypeHandle(
+ ParseTypeHandle("String"),
+ AsList(
+ CallableArgument(ParseTypeHandle("Int32")),
+ CallableArgument(ParseTypeHandle("Double?"), "bar", AsList("AutoMap"))
+ ),
+ 1
+ )
+); -- Callable<(Int32,['bar':Double?{Flags:AutoMap}])->String>
+```
+
+## LambdaArgumentsCount
+
+Получение количества аргументов в лямбда-функции.
+
+**Примеры:**
+``` yql
+SELECT LambdaArgumentsCount(($x, $y)->($x+$y))
+; -- 2
+```
+
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/aggregate.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/aggregate.md
new file mode 100644
index 00000000000..083cdd90c32
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/aggregate.md
@@ -0,0 +1,15 @@
+## Агрегатные функции {#aggregate-functions}
+
+Все [агрегатные функции](../../aggregation.md) также могут использоваться в роли оконных.
+В этом случае на каждой строке оказывается результат агрегации, полученный на множестве строк из [рамки окна](../../../syntax/window.md#frame).
+
+**Примеры:**
+``` yql
+SELECT
+ SUM(int_column) OVER w1 AS running_total,
+ SUM(int_column) OVER w2 AS total,
+FROM my_table
+WINDOW
+ w1 AS (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),
+ w2 AS ();
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/first_last_value.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/first_last_value.md
new file mode 100644
index 00000000000..38cc4899b37
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/first_last_value.md
@@ -0,0 +1,20 @@
+## FIRST_VALUE / LAST_VALUE
+
+Доступ к значениям из первой и последней строк [рамки окна](../../../syntax/window.md#frame). Единственный аргумент - выражение, к которому необходим доступ.
+
+Опционально перед `OVER` может указываться дополнительный модификатор `IGNORE NULLS`, который меняет поведение функций на первое или последнее __не пустое__ (то есть не `NULL`) значение среди строк рамки окна. Антоним этого модификатора — `RESPECT NULLS` является поведением по умолчанию и может не указываться.
+
+**Примеры**
+``` yql
+SELECT
+ FIRST_VALUE(my_column) OVER w
+FROM my_table
+WINDOW w AS (ORDER BY key);
+```
+
+``` yql
+SELECT
+ LAST_VALUE(my_column) IGNORE NULLS OVER w
+FROM my_table
+WINDOW w AS (ORDER BY key);
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/intro.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/intro.md
new file mode 100644
index 00000000000..48476f16312
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/intro.md
@@ -0,0 +1,2 @@
+# Список оконных функций в YQL
+Синтаксис вызова оконных функций подробно описан в [отдельной статье](../../../syntax/window.md).
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/lag_lead.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/lag_lead.md
new file mode 100644
index 00000000000..290d40b5730
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/lag_lead.md
@@ -0,0 +1,11 @@
+## LAG / LEAD {#lag-lead}
+
+Доступ к значению из строки [раздела](../../../syntax/window.md#partition), отстающей (`LAG`) или опережающей (`LEAD`) текущую на фиксированное число. В первом аргументе указывается выражение, к которому необходим доступ, а во втором — отступ в строках. Отступ можно не указывать, по умолчанию используется соседняя строка — предыдущая или следующая, соответственно, то есть подразумевается 1. В строках, для которых нет соседей с заданным расстоянием (например `LAG(expr, 3)` в первой и второй строках раздела), возвращается `NULL`.
+
+**Примеры**
+``` yql
+SELECT
+ int_value - LAG(int_value) OVER w AS int_value_diff
+FROM my_table
+WINDOW w AS (ORDER BY key);
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/rank_dense.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/rank_dense.md
new file mode 100644
index 00000000000..6be3093710e
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/rank_dense.md
@@ -0,0 +1,25 @@
+## RANK / DENSE_RANK {#rank}
+
+Пронумеровать группы соседних строк [раздела](../../../syntax/window.md#partition) с одинаковым значением выражения в аргументе. `DENSE_RANK` нумерует группы подряд, а `RANK` — пропускает `(N - 1)` значений, где `N` — число строк в предыдущей группе.
+
+При отсутствии аргумента использует порядок, указанный в секции `ORDER BY` определения окна.
+Если аргумент отсутствует и `ORDER BY` не указан, то все строки считаются равными друг другу.
+
+{% note info %}
+
+Возможность передавать аргумент в `RANK`/`DENSE_RANK` является нестандартным расширением YQL.
+
+{% endnote %}
+
+**Примеры**
+``` yql
+SELECT
+ RANK(my_column) OVER w
+FROM my_table
+WINDOW w AS (ORDER BY key);
+```
+``` yql
+SELECT
+ RANK() OVER w
+FROM my_table
+WINDOW w AS (ORDER BY my_column);
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/row_number.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/row_number.md
new file mode 100644
index 00000000000..cf3121ac80b
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/row_number.md
@@ -0,0 +1,11 @@
+## ROW_NUMBER {#row_number}
+
+Номер строки в рамках [раздела](../../../syntax/window.md#partition). Без аргументов.
+
+**Примеры**
+``` yql
+SELECT
+ ROW_NUMBER() OVER w AS row_num
+FROM my_table
+WINDOW w AS (ORDER BY key);
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/session_state.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/session_state.md
new file mode 100644
index 00000000000..e90a3f824f2
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/_includes/window/session_state.md
@@ -0,0 +1,4 @@
+## SessionState() {#session-state}
+
+Нестандартная оконная функция `SessionState()` (без аргументов) позволяет получить состояние расчета сессий из [SessionWindow](../../../syntax/group_by.md#session-window) для текущей строки.
+Допускается только при наличии `SessionWindow()` в секции `PARTITION BY` определения окна.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/aggregation.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/aggregation.md
new file mode 100644
index 00000000000..2d6f0e1f606
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/aggregation.md
@@ -0,0 +1,29 @@
+{% include [simple.md](_includes/aggregation/simple.md) %}
+
+{% include [count_distinct_estimate.md](_includes/aggregation/count_distinct_estimate.md) %}
+
+{% include [agg_list.md](_includes/aggregation/agg_list.md) %}
+
+{% include [max_min_by.md](_includes/aggregation/max_min_by.md) %}
+
+{% include [top_bottom.md](_includes/aggregation/top_bottom.md) %}
+
+{% include [topfreq_mode.md](_includes/aggregation/topfreq_mode.md) %}
+
+{% include [stddev_variance.md](_includes/aggregation/stddev_variance.md) %}
+
+{% include [corr_covar.md](_includes/aggregation/corr_covar.md) %}
+
+{% include [percentile_median.md](_includes/aggregation/percentile_median.md) %}
+
+{% include [histogram.md](_includes/aggregation/histogram.md) %}
+
+{% include [bool_bit.md](_includes/aggregation/bool_bit.md) %}
+
+{% if feature_window_functions %}
+
+ {% include [session_start.md](_includes/aggregation/session_start.md) %}
+
+{% endif %}
+
+{% include [aggregate_by.md](_includes/aggregation/aggregate_by.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/basic.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/basic.md
new file mode 100644
index 00000000000..b4262430aac
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/basic.md
@@ -0,0 +1,92 @@
+
+{% include [x](_includes/basic/intro.md) %}
+
+{% include [x](_includes/basic/coalesce.md) %}
+
+{% include [x](_includes/basic/length.md) %}
+
+{% include [x](_includes/basic/substring.md) %}
+
+{% include [x](_includes/basic/find.md) %}
+
+{% include [x](_includes/basic/starts_ends_with.md) %}
+
+{% include [x](_includes/basic/if.md) %}
+
+{% include [x](_includes/basic/nanvl.md) %}
+
+{% include [x](_includes/basic/random.md) %}
+
+{% include [x](_includes/basic/current_utc.md) %}
+
+{% include [x](_includes/basic/current_tz.md) %}
+
+{% include [x](_includes/basic/max_min.md) %}
+
+{% include [x](_includes/basic/as_container.md) %}
+
+{% include [x](_includes/basic/container_literal.md) %}
+
+{% include [x](_includes/basic/variant.md) %}
+
+{% include [x](_includes/basic/enum.md) %}
+
+{% include [x](_includes/basic/as_tagged.md) %}
+
+{% if feature_bulk_tables %}
+
+ {% include [x](_includes/basic/table_path_name_recindex.md) %}
+
+{% endif %}
+
+{% include [x](_includes/basic/table_row.md) %}
+
+{% if feature_mapreduce %}
+
+ {% include [x](_includes/basic/files.md) %}
+
+ {% include [x](_includes/basic/weakfield.md) %}
+
+{% endif %}
+
+{% include [x](_includes/basic/ensure.md) %}
+
+{% if feature_codegen %}
+
+ {% include [x](_includes/basic/evaluate_expr_atom.md) %}
+
+{% endif %}
+
+{% include [x](_includes/basic/data-type-literals.md) %}
+
+{% if feature_webui %}
+
+ {% include [x](_includes/basic/metadata.md) %}
+
+{% endif %}
+
+{% include [x](_includes/basic/to_from_bytes.md) %}
+
+{% include [x](_includes/basic/byteat.md) %}
+
+{% include [x](_includes/basic/bitops.md) %}
+
+{% include [x](_includes/basic/abs.md) %}
+
+{% include [x](_includes/basic/optional_ops.md) %}
+
+{% include [x](_includes/basic/callable.md) %}
+
+{% include [x](_includes/basic/pickle.md) %}
+
+{% include [x](_includes/basic/staticmap.md) %}
+
+{% include [x](_includes/basic/staticzip.md) %}
+
+{% include [x](_includes/basic/aggr_factory.md) %}
+
+{% if tech %}
+
+ {% include [x](_includes/basic/s_expressions.md) %}
+
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/codegen.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/codegen.md
new file mode 100644
index 00000000000..bc3bca2b116
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/codegen.md
@@ -0,0 +1,2 @@
+
+{% include [codegen.md](_includes/codegen.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/dict.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/dict.md
new file mode 100644
index 00000000000..24267d59a41
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/dict.md
@@ -0,0 +1,2 @@
+
+{% include [dict.md](_includes/dict.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/index.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/index.md
new file mode 100644
index 00000000000..b3cf50bcae9
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/index.md
@@ -0,0 +1,2 @@
+
+{% include [index.md](_includes/index.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/json.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/json.md
new file mode 100644
index 00000000000..4b454b1b634
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/json.md
@@ -0,0 +1,2 @@
+
+{% include [json.md](_includes/json.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/list.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/list.md
new file mode 100644
index 00000000000..a312392cda9
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/list.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/list.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/struct.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/struct.md
new file mode 100644
index 00000000000..418289d2530
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/struct.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/struct.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/toc_i.yaml b/ydb/docs/ru/core/yql/reference/yql-core/builtins/toc_i.yaml
new file mode 100644
index 00000000000..c9150e8046b
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/toc_i.yaml
@@ -0,0 +1,13 @@
+items:
+- { name: Обзор, href: index.md }
+- { name: Базовые, href: basic.md }
+- { name: Агрегатные, href: aggregation.md }
+- { name: Оконные, href: window.md, when: feature_window_functions }
+- { name: Для работы со списками, href: list.md }
+- { name: Для работы со словарями, href: dict.md }
+- { name: Для работы со структурами, href: struct.md }
+- { name: Для работы с типами, href: types.md }
+- { name: Для работы с генерацией кода, href: codegen.md, when: feature_codegen }
+- { name: Для работы с JSON, href: json.md }
+- name: Библиотеки C++
+ include: { mode: link, path: ../udf/list/toc_i.yaml } \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/types.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/types.md
new file mode 100644
index 00000000000..962e7b5fe24
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/types.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/types.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/builtins/window.md b/ydb/docs/ru/core/yql/reference/yql-core/builtins/window.md
new file mode 100644
index 00000000000..bd2e7be6c3b
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/builtins/window.md
@@ -0,0 +1,14 @@
+
+{% include [x](_includes/window/intro.md) %}
+
+{% include [x](_includes/window/aggregate.md) %}
+
+{% include [x](_includes/window/row_number.md) %}
+
+{% include [x](_includes/window/lag_lead.md) %}
+
+{% include [x](_includes/window/first_last_value.md) %}
+
+{% include [x](_includes/window/rank_dense.md) %}
+
+{% include [x](_includes/window/session_state.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_assets/join-YQL-06.png b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_assets/join-YQL-06.png
new file mode 100644
index 00000000000..88fb42f97fc
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_assets/join-YQL-06.png
Binary files differ
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/Readme.txt b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/Readme.txt
new file mode 100644
index 00000000000..3cc55b2121a
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/Readme.txt
@@ -0,0 +1,2 @@
+Files inside this folder represent YQL base blocks, and may NOT contain product-conditional content ({% if rtmr/ydb/yt/... == true %})
+It may not contain yandex-internal references either. \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/begin.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/begin.md
new file mode 100644
index 00000000000..13cf606ef66
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/begin.md
@@ -0,0 +1,19 @@
+## BEGIN .. END DO {#begin}
+
+Выполнение действия без его объявления (анонимное действие).
+
+**Синтаксис**
+1. `BEGIN`;
+1. Список выражений верхнего уровня;
+1. `END DO`.
+
+Анонимное действие не может содержать параметров.
+
+**Пример**
+
+```
+DO BEGIN
+ SELECT 1;
+ SELECT 2 -- здесь и в предыдущем примере ';' перед END можно не ставить
+END DO
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/define_do.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/define_do.md
new file mode 100644
index 00000000000..20825a5b4c4
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/define_do.md
@@ -0,0 +1,50 @@
+## DEFINE ACTION {#define-action}
+
+Задает именованное действие, которое представляют собой параметризуемый блок из нескольких выражений верхнего уровня.
+
+**Синтаксис**
+
+1. `DEFINE ACTION` — объявление действия.
+1. [Имя действия](../../expressions.md#named-nodes), по которому объявляемое действие доступно далее для вызова.
+1. В круглых скобках — список имен параметров.
+1. Ключевое слово `AS`.
+1. Список выражений верхнего уровня.
+1. `END DEFINE` — маркер последнего выражения внутри действия.
+
+Один или более последних параметров могут быть помечены знаком вопроса `?` как необязательные. Если они не будут указаны при вызове, то им будет присвоено значение `NULL`.
+
+## DO {#do}
+
+Выполняет `ACTION` с указанными параметрами.
+
+**Синтаксис**
+1. `DO` — выполнение действия.
+1. Именованное выражение, по которому объявлено действие.
+1. В круглых скобках — список значений для использования в роли параметров.
+
+`EMPTY_ACTION` — действие, которое ничего не выполняет.
+
+{% if feature_mapreduce %} <!-- In fact, if user file system integration is supported in the product. YQL service over YDB may also be here. -->
+
+{% note info "Примечание" %}
+
+В больших запросах объявление действий можно выносить в отдельные файлы и подключать их в основной запрос с помощью [EXPORT](../../export_import.md#export) + [IMPORT](../../export_import.md#import), чтобы вместо одного длинного текста получилось несколько логических частей, в которых проще ориентироваться. Важный нюанс: директива `USE my_cluster;` в импортирующем запросе не влияет на поведение объявленных в других файлах действий.
+
+{% endnote %}
+
+{% endif %}
+
+**Пример**
+
+```yql
+DEFINE ACTION $hello_world($name, $suffix?) AS
+ $name = $name ?? ($suffix ?? "world");
+ SELECT "Hello, " || $name || "!";
+END DEFINE;
+
+DO EMPTY_ACTION();
+DO $hello_world(NULL);
+DO $hello_world("John");
+DO $hello_world(NULL, "Earth");
+```
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/evaluate.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/evaluate.md
new file mode 100644
index 00000000000..63aa4c73a3c
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/action/evaluate.md
@@ -0,0 +1,72 @@
+## EVALUATE IF {#evaluate-if}
+`EVALUATE IF` — выполнение действия (action) в зависимости от выполнения условия. Далее указывается:
+
+1. Условие;
+2. [DO](#do) с именем и параметрами действия или анонимным действием;
+3. Опционально `ELSE` и следом второе `DO` для ситуации, когда условие не выполнено.
+
+## EVALUATE FOR {#evaluate-for}
+`EVALUATE FOR` — выполнение действия (action) для каждого элемента в списке. Далее указывается:
+
+1. [Именованное выражение](../../expressions.md#named-nodes), в которое будет подставляться каждый очередной элемент списка;
+2. Ключевое слово `IN`;
+3. Объявленное выше именованное выражение со списком, по которому будет выполняться действие.
+4. [DO](#do) с именем и параметрами действия или анонимным действием, в параметрах можно использовать как текущий элемент из первого пункта, так и любые объявленные выше именованные выражения, в том числе сам список.
+5. Опционально `ELSE` и следом второе `DO` для ситуации, когда список пуст.
+
+**Примеры**
+``` yql
+DEFINE ACTION $hello() AS
+ SELECT "Hello!";
+END DEFINE;
+
+DEFINE ACTION $bye() AS
+ SELECT "Bye!";
+END DEFINE;
+
+EVALUATE IF RANDOM(0) > 0.5
+ DO $hello()
+ELSE
+ DO $bye();
+
+EVALUATE IF RANDOM(0) > 0.1 DO BEGIN
+ SELECT "Hello!";
+END DO;
+
+EVALUATE FOR $i IN AsList(1, 2, 3) DO BEGIN
+ SELECT $i;
+END DO;
+```
+
+``` yql
+-- скопировать таблицу $input в $count новых таблиц
+$count = 3;
+$input = "my_input";
+$inputs = ListReplicate($input, $count);
+$outputs = ListMap(
+ ListFromRange(0, $count),
+ ($i) -> {
+ RETURN "tmp/out_" || CAST($i as String)
+ }
+);
+$pairs = ListZip($inputs, $outputs);
+
+DEFINE ACTION $copy_table($pair) as
+ $input = $pair.0;
+ $output = $pair.1;
+ INSERT INTO $output WITH TRUNCATE
+ SELECT * FROM $input;
+END DEFINE;
+
+EVALUATE FOR $pair IN $pairs
+ DO $copy_table($pair)
+ELSE
+ DO EMPTY_ACTION(); -- такой ELSE можно было не указывать,
+ -- ничего не делать подразумевается по умолчанию
+```
+
+{% note info "Примечание" %}
+
+Стоит учитывать, что `EVALUATE` выполняется до начала работы операции. Также в рамках `EVALUATE` невозможно использование [анонимных таблиц](../../select.md#temporary-tables).
+
+{% endnote %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/alter_table.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/alter_table.md
new file mode 100644
index 00000000000..87254812086
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/alter_table.md
@@ -0,0 +1,136 @@
+# ALTER TABLE
+
+При помощи команды ```ALTER TABLE``` можно изменить состав колонок и дополнительные параметры таблицы. В одной команде можно указать несколько действий. В общем случае команда ```ALTER TABLE``` выглядит так:
+
+```sql
+ALTER TABLE table_name action1, action2, ..., actionN;
+```
+
+```action``` — это любое действие по изменению таблицы, из описанных ниже.
+
+## Изменение состава колонок {#columns}
+
+{{ backend_name }} поддерживает возможность добавлять столбцы в таблицу, а также удалять неключевые колонки из таблицы.
+
+```ADD COLUMN``` — добавляет столбец с указанными именем и типом. Приведенный ниже код добавит к таблице ```episodes``` столбец ```is_deleted``` с типом данных ```Bool```.
+
+```sql
+ALTER TABLE episodes ADD COLUMN is_deleted Bool;
+```
+
+```DROP COLUMN``` — удаляет столбец с указанным именем. Приведенный ниже код удалит столбец ```is_deleted``` из таблицы ```episodes```.
+
+```sql
+ALTER TABLE episodes DROP column is_deleted;
+```
+
+{% if feature_secondary_index %}
+## Добавление или удаление вторичного индекса {#secondary-index}
+
+```ADD INDEX``` — добавляет индекс с указанным именем и типом для заданного набора колонок. Приведенный ниже код добавит глобальный индекс с именем ```title_index``` для колонки ```title```.
+
+```sql
+ALTER TABLE `series` ADD INDEX `title_index` GLOBAL ON (`title`);
+```
+
+Могут быть указаны все параметры индекса, описанные в команде [`CREATE TABLE`](../create_table#secondary_index)
+
+Удаление индекса:
+
+```DROP INDEX``` — удаляет индекс с указанным именем. Приведенный ниже код удалит индекс с именем ```title_index```.
+
+```sql
+ALTER TABLE `series` DROP INDEX `title_index`;
+```
+{% endif %}
+{% if feature_map_tables %}
+
+## Переименование таблицы {#rename}
+
+```sql
+ALTER TABLE old_table_name RENAME TO new_table_name;
+```
+
+Если таблица с новым именем существует, будет возвращена ошибка. Возможность транзакционной подмены таблицы под нагрузкой поддерживается специализированными методами в CLI и SDK.
+
+Если в YQL запросе содержится несколько команд `ALTER TABLE ... RENAME TO ...`, то каждая будет выполнена в режиме автокоммита в отдельной транзакции. С точки зрения внешнего процесса, таблицы будут переименованы последовательно одна за другой. Чтобы переименовать несколько таблиц в одной транзакции, используйте специализированные методы, доступные в CLI и SDK.
+
+Переименование может использоваться для перемещения таблицы из одной директории внутри БД в другую, например:
+
+``` sql
+ALTER TABLE `table1` RENAME TO `/backup/table1`;
+```
+
+## Изменение групп колонок {#column-family}
+
+```ADD FAMILY``` — создаёт новую группу колонок в таблице. Приведенный ниже код создаст в таблице ```series_with_families``` группу колонок ```family_small```.
+
+```sql
+ALTER TABLE series_with_families ADD FAMILY family_small (
+ DATA = "ssd",
+ COMPRESSION = "off"
+);
+```
+
+При помощи команды ```ALTER COLUMN``` можно изменить группу колонок для указанной колонки. Приведенный ниже код для колонки ```release_date``` в таблице ```series_with_families``` сменит группу колонок на ```family_small```.
+
+```sql
+ALTER TABLE series_with_families ALTER COLUMN release_date SET FAMILY family_small;
+```
+
+Две предыдущие команды из листингов 8 и 9 можно объединить в один вызов ```ALTER TABLE```. Приведенный ниже код создаст в таблице ```series_with_families``` группу колонок ```family_small``` и установит её для колонки ```release_date```.
+
+```sql
+ALTER TABLE series_with_families
+ ADD FAMILY family_small (
+ DATA = "ssd",
+ COMPRESSION = "off"
+ ),
+ ALTER COLUMN release_date SET FAMILY family_small;
+```
+
+При помощи команды ```ALTER FAMILY``` можно изменить параметры группы колонок. Приведенный ниже код для группы колонок ```default``` в таблице ```series_with_families``` сменит тип хранилища на ```hdd```:
+
+```sql
+ALTER TABLE series_with_families ALTER FAMILY default SET DATA "hdd";
+```
+
+Могут быть указаны все параметры группы колонок, описанные в команде [`CREATE TABLE`](create_table#column-family)
+
+
+## Изменение дополнительных параметров таблицы {#additional-alter}
+
+Большинство параметров таблицы в YDB, приведенных на странице [описания таблицы]({{ concept_table }}), можно изменить командой ```ALTER```.
+
+В общем случае команда для изменения любого параметра таблицы выглядит следующим образом:
+
+```sql
+ALTER TABLE table_name SET (key = value);
+```
+
+```key``` — имя параметра, ```value``` — его новое значение.
+
+Например, такая команда выключит автоматическое партиционирование таблицы:
+
+```sql
+ALTER TABLE series SET (AUTO_PARTITIONING_BY_SIZE = DISABLED);
+```
+
+## Сброс дополнительных параметров таблицы {#additional-reset}
+
+Некоторые параметры таблицы в YDB, приведенные на странице [описания таблицы]({{ concept_table }}), можно сбросить командой ```ALTER```.
+
+Команда для сброса параметра таблицы выглядит следующим образом:
+
+```sql
+ALTER TABLE table_name RESET (key);
+```
+
+```key``` — имя параметра.
+
+Например, такая команда сбросит (удалит) настройки TTL для таблицы:
+
+```sql
+ALTER TABLE series RESET (TTL);
+```
+{% endif %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/create_table.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/create_table.md
new file mode 100644
index 00000000000..e029a124d8a
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/create_table.md
@@ -0,0 +1,163 @@
+# CREATE TABLE
+
+{% if feature_bulk_tables %}
+
+Таблица создается автоматически при первом [INSERT INTO](insert_into.md){% if feature_mapreduce %}, в заданной оператором [USE](../use.md) базе данных{% endif %}. Схема при этом определяется автоматически.
+
+{% else %}
+
+Вызов `CREATE TABLE` создает {% if concept_table %}[таблицу]({{ concept_table }}){% else %}таблицу{% endif %} с указанной схемой данных{% if feature_map_tables %} и ключевыми колонками (`PRIMARY KEY`){% endif %}. {% if feature_secondary_index == true %}Позволяет определить вторичные индексы на создаваемой таблице.{% endif %}
+
+ CREATE TABLE table_name (
+ column1 type1,
+{% if feature_not_null == true %} column2 type2 NOT NULL,{% else %} column2 type2,{% endif %}
+ ...
+ columnN typeN,
+{% if feature_secondary_index == true %}
+ INDEX index1_name GLOBAL ON ( column ),
+ INDEX index2_name GLOBAL ON ( column1, column2, ... ),
+{% endif %}
+{% if feature_map_tables %}
+ PRIMARY KEY (column, ...),
+ FAMILY column_family ()
+{% else %}
+ ...
+{% endif %}
+ )
+{% if feature_map_tables %}
+ WITH ( key = value, ... )
+{% endif %}
+
+## Колонки {#columns}
+
+{% if feature_column_container_type == true %}
+Для неключевых колонок допускаются любые типы данных, для ключевых - только [примитивные](../../types/primitive.md). При указании сложных типов (например, `List<String>`) тип заключается в двойные кавычки.
+{% else %}
+Для ключевых и неключевых колонок допускаются только [примитивные](../../types/primitive.md) типы данных.
+{% endif %}
+
+{% if feature_not_null == true %}
+Без дополнительных модификаторов колонка приобретает [опциональный тип](../../types/optional.md) тип, и допускает запись `NULL` в качестве значений. Для получения неопционального типа необходимо использовать `NOT NULL`.
+{% else %}
+Все колонки допускают запись `NULL` в качестве значений, то есть являются [опциональными](../../types/optional.md).
+{% endif %}
+{% if feature_map_tables %}
+Обязательно указание `PRIMARY KEY` с непустым списком колонок. Эти колонки становятся частью ключа в порядке перечисления.
+{% endif %}
+
+**Пример**
+
+ CREATE TABLE my_table (
+ a Uint64,
+ b Bool,
+{% if feature_not_null %} c Float NOT NULL,{% else %} c Float,{% endif %}
+{% if feature_column_container_type %} d "List<List<Int32>>"{% endif %}
+{% if feature_map_tables %}
+ PRIMARY KEY (b, a)
+{% endif %}
+ )
+
+
+
+{% if feature_secondary_index %}
+## Вторичные индексы {#secondary_index}
+
+Конструкция INDEX используется для определения {% if concept_secondary_index %}[вторичного индекса]({{ concept_secondary_index }}){% else %}вторичного индекса{% endif %} на таблице:
+
+```sql
+CREATE TABLE table_name (
+ ...
+ INDEX <Index_name> GLOBAL [SYNC|ASYNC] ON ( <Index_columns> ) COVER ( <Cover_columns> ),
+ ...
+)
+```
+
+где:
+* **Index_name** - уникальное имя индекса, по которому будет возможно обращение к данным
+* **SYNC/ASYNC** - синхронная или асинхронная запись в индекс, если не указано -- синхронная
+* **Index_columns** - имена колонок создаваемой таблицы через запятую, по которым возможен поиск в индексе
+* **Cover_columns** - имена колонок создаваемой таблицы через запятую, которые будет сохранены в индексе дополнительное к колонкам поиска, давая возможность получить дополнительные данные без обращения за ними в таблицу
+
+**Пример**
+
+``` sql
+CREATE TABLE my_table (
+ a Uint64,
+ b Bool,
+ c Uft8,
+ d Date,
+ INDEX idx_a GLOBAL ON (d),
+ INDEX idx_ca GLOBAL ASYNC ON (b, a) COVER ( c ),
+ PRIMARY KEY (a)
+)
+```
+{% endif %}
+
+{% if feature_map_tables and concept_table %}
+## Дополнительные параметры {#additional}
+
+Для таблицы может быть указан ряд специфичных для {{ backend_name }} параметров. При создании таблицы, используя YQL, такие параметры перечисляются в блоке ```WITH```:
+
+```sql
+CREATE TABLE table_name (...)
+WITH (
+ key1 = value1,
+ key2 = value2,
+ ...
+)
+```
+
+Здесь key — это название параметра, а value — его значение.
+
+Перечень допустимых имен параметров и их значений приведен на странице [описания таблицы {{ backend_name }}]({{ concept_table }})
+
+Например, такой код создаст таблицу с включенным автоматическим партиционированием по размеру партиции и предпочитаемым размером каждой партиции 512 мегабайт:
+
+<small>Листинг 4</small>
+
+```sql
+CREATE TABLE my_table (
+ id Uint64,
+ title Utf8,
+ PRIMARY KEY (id)
+)
+WITH (
+ AUTO_PARTITIONING_BY_SIZE = ENABLED,
+ AUTO_PARTITIONING_PARTITION_SIZE_MB = 512
+);
+```
+
+## Группы колонок {#column-family}
+
+Колонки одной таблицы можно объединять в группы, для того чтобы задать следующие параметры:
+
+* `DATA` — тип хранилища для данных колонок этой группы. Допустимые значения: ```"ssd"```, ```"hdd"```.
+* `COMPRESSION` — кодек сжатия данных. Допустимые значения: ```"off"```, ```"lz4"```.
+
+По умолчанию все колонки находятся в одной группе с именем ```default```. При желании, параметры этой группы тоже можно переопределить.
+
+В примере ниже для создаваемой таблицы добавляется группа колонок ```family_large``` и устанавливается для колонки ```series_info```, а также переопределяются параметры для группы ```default```, которая по умолчанию установлена для всех остальных колонок.
+
+```sql
+CREATE TABLE series_with_families (
+ series_id Uint64,
+ title Utf8,
+ series_info Utf8 FAMILY family_large,
+ release_date Uint64,
+ PRIMARY KEY (series_id),
+ FAMILY default (
+ DATA = "ssd",
+ COMPRESSION = "off"
+ ),
+ FAMILY family_large (
+ DATA = "hdd",
+ COMPRESSION = "lz4"
+ )
+);
+```
+
+{% endif %}
+
+
+
+{% endif %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/declare/general.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/declare/general.md
new file mode 100644
index 00000000000..01d78f93e33
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/declare/general.md
@@ -0,0 +1,35 @@
+# DECLARE
+
+Объявляет типизированное [именованное выражение](../../expressions.md#named-nodes), значение для которого будет передано параметром отдельно от текста запроса. Параметризация дает возможность отделить разработку аналитического решения задачи от её запуска с различными вариантами входных значений.
+
+Для транзакционной нагрузки использование параметров позволяет избежать перекомпиляции запросов при повторении однотипных вызовов, снижая потребление ресурсов сервера, и исключая время компиляции из общего времени исполнения запроса.
+
+Передача параметров поддерживается в SDK, CLI, и в графических интерфейсах.
+
+**Синтаксис**
+
+```sql
+DECLARE $named-node AS data_type;
+```
+1. Ключевое слово `DECLARE`.
+1. `$named-node` — имя, по которому можно будет обращаться к переданному значению, должно начинаться с символа `$`.
+1. Ключевое слово `AS`.
+1. `data_type` — тип данных [в виде строки в принятом формате](../../../types/type_string.md).
+
+Допустимы только сериализуемые типы данных:
+
+* [Примитивные типы](../../../types/primitive.md).
+* [Опциональные типы](../../../types/optional.md).
+* [Контейнеры](../../../types/containers.md) за исключением `Stream<Type>`.
+* `Void` и `Null`— поддерживаемые [специальные типы](../../../types/special.md).
+
+**Пример**
+
+``` yql
+DECLARE $x AS String;
+DECLARE $y AS String?;
+DECLARE $z AS List<String>;
+
+SELECT $x, $y, $z;
+```
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/delete.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/delete.md
new file mode 100644
index 00000000000..110792d38bb
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/delete.md
@@ -0,0 +1,35 @@
+# DELETE FROM
+
+Удаляет строки из таблицы, заданные с помощью условия `WHERE`.{% if feature_mapreduce %} Таблица по имени ищется в базе данных, заданной оператором [USE](../use.md).{% endif %}
+
+{% note info %}
+
+Изменение состояния таблицы не отслеживается в рамках одной транзакции. Если таблица уже была изменена, для удаления данных в той же транзакции используйте [`DELETE ON`](#delete-on).
+
+{% endnote %}
+
+**Пример**
+
+```sql
+DELETE FROM my_table
+WHERE Key1 == 1 AND Key2 >= "One";
+COMMIT;
+```
+
+## DELETE FROM ... ON {#delete-on}
+
+Используется для удаления данных, если таблица уже была изменена ранее в рамках одной транзакции.
+
+**Пример**
+
+```sql
+$to_delete = (
+ SELECT Key, SubKey FROM my_table WHERE Value = "ToDelete"
+);
+
+SELECT * FROM my_table;
+
+DELETE FROM my_table ON
+SELECT * FROM $to_delete;
+COMMIT;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/discard.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/discard.md
new file mode 100644
index 00000000000..ec71dabb237
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/discard.md
@@ -0,0 +1,30 @@
+# DISCARD
+
+Вычисляет {% if select_command == "SELECT STREAM" %}[`SELECT STREAM`](../select_stream.md){% else %}[`SELECT`](../select.md){% endif %}{% if feature_mapreduce %}{% if reduce_command %}, [`{{ reduce_command }}`](../reduce.md){% endif %} или [`{{ process_command }}`](../process.md){% endif %}, но не возвращает результат ни в клиент, ни в таблицу. {% if feature_mapreduce %}Не может быть задано одновременно с [INTO RESULT](../into_result.md).{% endif %}
+
+Полезно использовать в сочетании с [`Ensure`](../../builtins/basic.md#ensure) для проверки выполнения пользовательских условий на финальный результат вычислений.
+
+{% if select_command != true or select_command == "SELECT" %}
+**Примеры**
+
+``` yql
+DISCARD SELECT 1;
+```
+
+``` yql
+INSERT INTO result_table WITH TRUNCATE
+SELECT * FROM
+my_table
+WHERE value % 2 == 0;
+
+COMMIT;
+
+DISCARD SELECT Ensure(
+ 0, -- will discard result anyway
+ COUNT(*) > 1000,
+ "Too small result table, got only " || CAST(COUNT(*) AS String) || " rows"
+) FROM result_table;
+
+```
+
+{% endif %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/drop_table.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/drop_table.md
new file mode 100644
index 00000000000..a2a19567b3e
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/drop_table.md
@@ -0,0 +1,11 @@
+# DROP TABLE
+
+Удаляет указанную таблицу.{% if feature_mapreduce %} Таблица по имени ищется в базе данных, заданной оператором [USE](../use.md).{% endif %}
+
+Если таблицы с таким именем не существует, возвращается ошибка.
+
+**Примеры:**
+
+``` yql
+DROP TABLE my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/export_import.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/export_import.md
new file mode 100644
index 00000000000..a8a10ef2d34
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/export_import.md
@@ -0,0 +1,56 @@
+# Вынос части запроса в отдельный файл
+
+Механизм для выноса части запроса в отдельный приложенный файл:
+
+* [PRAGMA Library](../pragma.md#library) помечает приложенный файл как доступный для импорта.
+## `Export`
+* В `EXPORT $my_symbol1, $my_symbol2, ...;` перечисляется список именованных выражений в библиотеке, доступных для импорта.
+## `Import`
+* `IMPORT my_library SYMBOLS $my_symbol1, $my_symbol2, ...;` делает перечисленные именованные выражения доступными для использования ниже.
+
+{% note info "Примечание" %}
+
+В библиотеку могут быть вынесены [лямбды](../expressions.md#lambda), [действия](../action.md){% if feature_subquery %}, [именованные подзапросы](../subquery.md){% endif %}, константы и выражения, но __не подзапросы и не агрегатные функции__.
+
+{% endnote %}
+
+{% note warning "Предупреждение" %}
+
+Файл, на который ссылается [PRAGMA Library](../pragma.md#library) должен быть приложен к запросу. __Использовать для этой цели [PRAGMA File](../pragma.md#file) нельзя__.
+
+{% endnote %}
+
+
+**Примеры:**
+
+my_lib.sql:
+``` yql
+$Square = ($x) -> { RETURN $x * $x; };
+$Sqrt = ($x) -> { RETURN Math::Sqrt($x); };
+
+-- Агрегационные функции, создаваемые с помощью
+-- AggregationFactory, удобно выносить в библиотеку
+$Agg_sum = AggregationFactory("SUM");
+$Agg_max = AggregationFactory("MAX");
+
+EXPORT $Square, $Sqrt, $Agg_sum, $Agg_max;
+```
+
+Запрос:
+``` yql
+PRAGMA Library("my_lib.sql");
+IMPORT my_lib SYMBOLS $Square, $Sqrt, $Agg_sum, $Agg_max;
+SELECT
+ $Square(2), -- 4
+ $Sqrt(4); -- 2
+
+SELECT
+ AGGREGATE_BY(x, $Agg_sum), -- 5
+ AGGREGATE_BY(x, $Agg_max) -- 3
+FROM (
+ SELECT 2 AS x
+ UNION ALL
+ SELECT 3 AS x
+)
+```
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/as.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/as.md
new file mode 100644
index 00000000000..98f36605db3
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/as.md
@@ -0,0 +1,40 @@
+## AS {#as}
+
+Может использоваться в следующих сценариях:
+
+* Присвоение короткого имени (алиаса) столбцам или таблицам в рамках запроса.
+* Указание именованных аргументов при вызове функций.
+* При явном приведении типов данных для указания целевого типа, см. [CAST](#cast).
+
+{% if select_command != "SELECT STREAM" %}
+**Примеры:**
+
+``` yql
+SELECT key AS k FROM my_table;
+```
+
+``` yql
+SELECT t.key FROM my_table AS t;
+```
+
+``` yql
+SELECT
+ MyFunction(key, 123 AS my_optional_arg)
+FROM my_table;
+```
+{% else %}
+**Примеры:**
+``` yql
+SELECT STREAM key AS k FROM my_stream;
+```
+
+``` yql
+SELECT STREAM s.key FROM my_stream AS s;
+```
+
+``` yql
+SELECT STREAM
+ MyFunction(key, 123 AS my_optional_arg)
+FROM my_stream;
+```
+{% endif %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/between.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/between.md
new file mode 100644
index 00000000000..a8c1e3bc3d2
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/between.md
@@ -0,0 +1,11 @@
+## BETWEEN {#between}
+
+Проверка на вхождение значения в диапазон. Эквивалентно паре условий с `>=` и `<=`, то есть границы диапазона включаются. Может использоваться с префиксом `NOT` для инверсии.
+
+**Примеры**
+
+``` yql
+SELECT * FROM my_table
+WHERE key BETWEEN 10 AND 20;
+```
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/bitcast.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/bitcast.md
new file mode 100644
index 00000000000..117f54fb917
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/bitcast.md
@@ -0,0 +1,12 @@
+## BITCAST {#bitcast}
+Выполняет побитное преобразование целочисленного значения к указанному целочисленному типу. Преобразование всегда успешно, но может потерять точность или старшие биты.
+
+**Примеры**
+``` yql
+SELECT
+ BITCAST(100000ul AS Uint32), -- 100000
+ BITCAST(100000ul AS Int16), -- -31072
+ BITCAST(100000ul AS Uint16), -- 34464
+ BITCAST(-1 AS Int16), -- -1
+ BITCAST(-1 AS Uint16); -- 65535
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/case.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/case.md
new file mode 100644
index 00000000000..09578bf67a8
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/case.md
@@ -0,0 +1,31 @@
+## CASE {#case}
+
+Условные выражения и ветвление. Аналог `if`, `switch` и тернарных операторов в императивных языках программирования.
+Если результатом выражения `WHEN` оказывается `true`, значением выражения `CASE` становится результат,
+следующий за условием, а остальная часть выражения `CASE` не вычисляется. Если же условие не выполняется,
+за ним таким же образом проверяются все последующие предложения `WHEN`. Если не выполняется
+ни одно из условий `WHEN`, значением `CASE` становится результат, записанный в предложении `ELSE`.
+Ветка `ELSE` является обязательной в выражении `CASE`. Выражения в `WHEN` проверяются последовательно, сверху вниз.
+
+Так как синтаксис достаточно громоздкий, зачастую удобнее пользоваться встроенной функцией [IF](../../../builtins/basic.md#if).
+
+**Примеры**
+``` yql
+SELECT
+ CASE
+ WHEN value > 0
+ THEN "positive"
+ ELSE "negative"
+ END
+FROM my_table;
+```
+
+``` yql
+SELECT
+ CASE value
+ WHEN 0 THEN "zero"
+ WHEN 1 THEN "one"
+ ELSE "not zero or one"
+ END
+FROM my_table;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/cast.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/cast.md
new file mode 100644
index 00000000000..e8a099e2985
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/cast.md
@@ -0,0 +1,14 @@
+## CAST {#cast}
+
+Пробует привести значение к указанному типу. Попытка может оказаться неуспешной и вернуть `NULL`. Для чисел может потерять точность или старшие биты.
+{% if feature_column_container_type %}
+Для списков и словарей может либо удалить, либо заменить на `NULL` элементы, преобразование которых неудачно.
+Для структур и кортежей удаляет элементы, которых нет в целевом типе.
+Подробнее правила преобразований описаны [здесь](../../../types/cast.md).
+{% endif %}
+
+{% include [decimal_args](../../../_includes/decimal_args.md) %}
+
+**Примеры**
+
+{% include [cast_examples](../../../_includes/cast_examples.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/check-match.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/check-match.md
new file mode 100644
index 00000000000..f72964add24
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/check-match.md
@@ -0,0 +1,43 @@
+## Проверка строки на соответствие шаблону {#check-match}
+
+`REGEXP` и `RLIKE` являются алиасами и представляют собой короткий способ записи для вызова [Hyperscan::Grep](../../../udf/list/hyperscan.md#grep). `MATCH` — аналогично для [Hyperscan::Match](../../../udf/list/hyperscan.md#match).
+
+`LIKE` работает по следующим принципам:
+
+* В шаблонах используется два спецсимвола:
+ * `%` — ноль и более любых символов;
+ * `_` — ровно один любой символ.
+ Все остальные символы выступают как литералы, то есть обозначают сами себя.
+* В отличие от `REGEXP`, с шаблоном `LIKE` строка должна совпасть полностью. Например, для поиска подстроки в середине нужно добавить `%` в начале и в конце шаблона.
+* `ILIKE` является не чувствительной к регистру версией `LIKE`.
+* Если `LIKE` применяется к ключевой колонке сортированной таблицы и шаблон начинается не со спецсимвола, то фильтрация по префиксу опускается прямо до кластера, что в некоторых случаях позволяет не сканировать всю таблицу целиком. Для `ILIKE` данная оптимизация отключена.
+* Чтобы заэкранировать спецсимволы, необходимо после шаблона указать символ для экранирования с помощью ключевого слова `ESCAPE '?'`. Вместо `?` можно использовать любой символ, кроме `%` и `_`. Например, если в качестве экранирующего символа используется знак вопроса, то выражения `?%`, `?_` и `??` в шаблоне совпадут со своим вторым символом: процент, подчеркивание и знак вопроса, соответственно. По умолчанию экранирующий символ не определен.
+
+Наиболее популярный способ использования ключевых слов `LIKE` и `REGEXP` — фильтрация таблицы в выражениях с `WHERE`. Однако ограничения на использование шаблонов именно в этом контексте нет, и их можно использовать в большинстве контекстов при работе со строками, наравне, например, с конкатенацией с помощью `||`.
+
+**Примеры**
+``` yql
+SELECT * FROM my_table
+WHERE string_column REGEXP '\\d+';
+-- второй слеш нужен, так как все
+-- стандартные строковые литералы в SQL
+-- могут принимать С-escaped строки
+```
+
+``` yql
+SELECT
+ string_column LIKE '___!_!_!_!!!!!!' ESCAPE '!'
+ -- ищет строку из ровно 9 символов:
+ -- 3 произвольных,
+ -- затем 3 подчеркивания
+ -- и 3 восклицательных знака
+FROM my_table;
+```
+
+``` yql
+SELECT * FROM my_table
+WHERE key LIKE 'foo%bar';
+-- вероятно, физически просканирует только ключи,
+-- начинающиеся на foo, и затем среди них
+-- оставит только заканчивающиеся на bar
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/concatenation.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/concatenation.md
new file mode 100644
index 00000000000..74fa8be6b55
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/concatenation.md
@@ -0,0 +1,13 @@
+## Конкатенация строк {#concatenation}
+
+Выполняется через бинарный оператор `||`.
+
+Как и у других бинарных операторов, если в данных с одной из сторон оказался `NULL`, то и результат будет `NULL`.
+
+Не следует путать этот оператор с логическим «или», в SQL оно обозначается ключевым словом `OR`. Также не стоит пытаться делать конкатенацию через `+`.
+
+**Примеры**
+
+```sql
+SELECT "fo" || "o";
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/in.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/in.md
new file mode 100644
index 00000000000..2cae08f8a0e
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/in.md
@@ -0,0 +1,44 @@
+## IN {#in}
+Проверка вхождения одного значения в набор значений. Логически эквивалентно цепочке сравнений на равенство через `OR`, но реализовано более эффективно.
+
+{% note warning "Внимание" %}
+
+В отличие от аналогичного ключевого слова в Python, в YQL `IN` **НЕ** является поиском подстроки в строке. Для поиска подстроки можно использовать функцию [String::Contains](../../../udf/list/string.md) или описанные выше [LIKE / REGEXP](#like).
+
+{% endnote %}
+
+Сразу после `IN` можно указать хинт `COMPACT`.
+Если `COMPACT` не указан, то `IN` с подзапросом по возможности выполняется как соответствующий `JOIN` (`LEFT SEMI` для `IN` и `LEFT ONLY` для `NOT IN`).
+Наличие хинта `COMPACT` форсирует in-memory стратегию выполнения: из содержимого правой части `IN` в памяти сразу строится хеш-таблица, по которой затем фильтруется левая часть.
+
+Хинтом `COMPACT` следует пользоваться с осторожностью. Поскольку хеш-таблица строится в памяти, то запрос может упасть, если правая часть `IN` содержит много больших и/или различных элементов.
+
+{% if feature_mapreduce %}
+Так как в YQL есть лимит на размер запроса в байтах (порядка 1Мб), для больших списков значений нужно прикладывать их к запросу через URL и пользоваться функцией [ParseFile](../../../builtins/basic.md#parsefile).
+{% endif %}
+
+**Примеры**
+
+``` yql
+SELECT column IN (1, 2, 3)
+FROM my_table;
+```
+
+``` yql
+SELECT * FROM my_table
+WHERE string_column IN ("a", "b", "c");
+```
+
+``` yql
+$foo = AsList(1, 2, 3);
+SELECT 1 IN $foo;
+```
+
+``` yql
+$values = (SELECT column + 1 FROM table);
+SELECT * FROM my_table WHERE
+ -- фильтрация по in-memory хеш-таблице на основе table
+ column1 IN COMPACT $values AND
+ -- с последующим LEFT ONLY JOIN с other_table
+ column2 NOT IN (SELECT other_column FROM other_table);
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/is-distinct-from.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/is-distinct-from.md
new file mode 100644
index 00000000000..25b3095344c
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/is-distinct-from.md
@@ -0,0 +1,11 @@
+## IS \[NOT\] DISTINCT FROM {#is-distinct-from}
+
+Сравнение двух значений. В отличие от обычных [операторов сравнения](#comparison-operators), нуллы считаются равными друг другу.
+Точнее говоря, сравнение осуществляется по следующим правилам:
+1) операторы `IS DISTINCT FROM`/`IS NOT DISTINCT FROM` определены для тех и только для тех аргументов, для которых определены операторы `!=` и `=`;
+2) результат `IS NOT DISTINCT FROM` равен логическому отрицанию результата `IS DISTINCT FROM` для данных аргументов;
+3) если результат оператора `==` не равен нуллу для некоторых аргументов, то он совпадает с результатом оператора `IS NOT DISTINCT FROM` для тех же аргументов;
+4) если оба аргумента являются незаполненными `Optional`ми или `NULL`ами, то значение `IS NOT DISTINCT FROM` равно `True`
+5) результат `IS NOT DISTINCT FROM` от незаполненного `Optional` или `NULL` и заполненного `Optional` или не-`Optional` значения равен `False`.
+
+Для значений композитных типов эти правила применяются рекурсивно. \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/is-null.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/is-null.md
new file mode 100644
index 00000000000..bec5aa81679
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/is-null.md
@@ -0,0 +1,10 @@
+## IS \[NOT\] NULL {#is-null}
+
+Проверка на пустое значение (`NULL`). Так как `NULL` является особым значением, которое [ничему не равно](../../../types/optional.md#null_expr), то обычные [операторы сравнения](#comparison-operators) для этой задачи не подходят.
+
+**Примеры**
+
+``` yql
+SELECT key FROM my_table
+WHERE value IS NOT NULL;
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/items-access.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/items-access.md
new file mode 100644
index 00000000000..7ba6dec11ec
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/items-access.md
@@ -0,0 +1,26 @@
+## Обращение к контейнерам {#items-access}
+
+Для адресации к значениям внутри контейнеров:
+
+* `Struct<>`, `Tuple<>` и `Variant<>` — используется **точка**. Набор ключей (для кортежа и соответствующего варианта — индексов) известен в момент компиляции запроса. Валидность ключа **проверяется** до начала выполнения запроса.
+* `List<>` и `Dict<>` — используются **квадратные скобки**. Набор ключей (для списка — индексов) известен только во время выполнения запроса. Валидность ключа **не проверяется** до начала выполнения запроса. Если значение не найдено — будет возвращено пустое значение (NULL)
+
+[Описание и список доступных контейнеров](../../../types/containers.md).
+
+При использовании этого синтаксиса для обращения к контейнерам в столбцах таблиц обязательно нужно указывать полное имя столбца, включая имя или алиас таблицы через точку (см. первый пример ниже).
+
+**Примеры**
+
+``` yql
+SELECT
+ t.struct.member,
+ t.tuple.7,
+ t.dict["key"],
+ t.list[7]
+FROM my_table AS t;
+```
+
+``` yql
+SELECT
+ Sample::ReturnsStruct().member;
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/lambda.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/lambda.md
new file mode 100644
index 00000000000..68aeb2afdb6
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/lambda.md
@@ -0,0 +1,32 @@
+## Lambda функции {#lambda}
+
+Позволяют комбинировать несколько выражений в одно вызываемое значение.
+
+В круглых скобках перечисляются аргументы, далее после стрелки указывается тело lambda. Тело lambda состоит либо из выражения в круглых скобках, либо из фигурных скобок вокруг необязательной цепочки выражений с присвоением [именованных выражений](#named-nodes) и результата вызова после ключевого слова `RETURN` в последнем выражении.
+
+Область видимости для тела lambda — сначала локальные именованные выражения, затем аргументы, затем именованные выражения, определенные выше lambda на верхнем уровне запроса.
+
+В теле lambda можно использовать только чистые выражения — в том числе другие lambda, возможно, переданные через аргументы. Но нельзя использовать [SELECT](../../select.md), [INSERT INTO](../../insert_into.md) и прочие выражения верхнего уровня.
+
+Один или более последних параметров lambda могут быть помечены вопросиком как необязательные — если они не были указаны при вызове lambda, то им будет присвоено значение `NULL`.
+
+**Примеры**
+
+``` yql
+$f = ($y) -> {
+ $prefix = "x";
+ RETURN $prefix || $y;
+};
+
+$g = ($y) -> ("x" || $y);
+
+$h = ($x, $y?) -> ($x + ($y ?? 0));
+
+SELECT $f("y"), $g("z"), $h(1), $h(2, 3); -- "xy", "xz", 1, 5
+```
+
+``` yql
+-- если результат лямбды вычисляется единственным выражением, то можно использовать более компактный вариант синтаксиса:
+$f = ($x, $_) -> ($x || "suffix"); -- второй аргумент не используется
+SELECT $f("prefix_", "whatever");
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/named-nodes.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/named-nodes.md
new file mode 100644
index 00000000000..b2789ffce1f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/named-nodes.md
@@ -0,0 +1,83 @@
+## Именованные выражения {#named-nodes}
+
+Сложные запросы могут выглядеть громоздко и содержать много уровней вложенности и/или повторяющихся частей. В YQL имеется возможность использовать именованные выражения – способ назначить имя произвольному выражению или подзапросу. На это именованное выражение можно ссылаться в других выражениях или подзапросах. При этом фактически происходит подстановка исходного выражения/подзапроса по месту использования.
+
+Именованное выражение определяется следующим образом:
+```
+<named-expr> = <expression> | <subquery>;
+```
+Здесь `<named-expr>` состоит из символа $ и произвольного непустого идентификатора (например `$foo`).
+
+Если выражение в правой части представляет собой кортеж, то его можно автоматически распаковать, указав в левой части несколько именованных выражений через запятую:
+```
+<named-expr1>, <named-expr2>, <named-expr3> ... = <expression-returning-tuple>;
+```
+В этом случае число выражений должно совпадать с размером кортежа.
+
+У каждого именованного выражения есть область видимости. Она начинается сразу после определения именованного выражения и заканчивается в конце ближайшего охватывающего scope имен (например в конце запроса либо в конце тела [лямбда-функции](#lambda), [ACTION](../../action.md#define-action){% if feature_subquery %}, [SUBQUERY](../../subquery.md#define-subquery){% endif %}{% if feature_mapreduce %} или цикла [EVALUATE FOR](../../action.md#evaluate-for){% endif %}).
+Повторное определение именованного выражения с тем же именем приводит к сокрытию предыдущего выражения из текущей области видимости.
+
+Если именованное выражение ни разу не использовалось, то генерируется предупреждение. Для того, чтобы избавиться от такого предупреждения, достаточно использовать символ подчеркивания в качестве первого символа идентификатора (например `$_foo`).
+Именованное выражение `$_` называется анонимным именованным выражением и обрабатывается специальным образом: оно работает, как если бы `$_` автоматически заменялось на `$_<some_uniq_name>`.
+Анонимными именованными выражениями удобно пользоваться в тех случаях, когда мы не интересуемся его значением. Например, для извлечения второго элемента из кортежа из трех элементов можно написать:
+```yql
+$_, $second, $_ = AsTuple(1, 2, 3);
+select $second;
+```
+
+Попытка сослаться на анонимное именованное выражение приводит к ошибке:
+```yql
+$_ = 1;
+select $_; --- ошибка: Unable to reference anonymous name $_
+export $_; --- ошибка: Can not export anonymous name $_
+```
+{% if feature_mapreduce %}
+Кроме того, нельзя импортировать именованное выражение под анонимным алиасом:
+```yql
+import utils symbols $sqrt as $_; --- ошибка: Can not import anonymous name $_
+```
+{% endif %}
+Анонимные имена аргументов поддерживаются также для [лямбда-функций](#lambda), [ACTION](../../action.md#define-action){% if feature_subquery %}, [SUBQUERY](../../subquery.md#define-subquery){% endif %}{% if feature_mapreduce %} и в [EVALUATE FOR](../../action.md#evaluate-for){% endif %}.
+
+{% note info %}
+
+Если в результате подстановки именованных выражений в графе выполнения запроса получились полностью одинаковые подграфы, они объединяются, чтобы такой подграф выполнялся только один раз.
+
+{% endnote %}
+
+**Примеры**
+
+``` yql
+$multiplier = 712;
+SELECT
+ a * $multiplier, -- $multiplier is 712
+ b * $multiplier,
+ (a + b) * $multiplier
+FROM abc_table;
+$multiplier = c;
+SELECT
+ a * $multiplier -- $multiplier is column c
+FROM abc_table;
+```
+
+``` yql
+$intermediate = (
+ SELECT
+ value * value AS square,
+ value
+ FROM my_table
+);
+SELECT a.square * b.value
+FROM $intermediate AS a
+INNER JOIN $intermediate AS b
+ON a.value == b.square;
+```
+
+``` yql
+$a, $_, $c = AsTuple(1, 5u, "test"); -- распаковка кортежа
+SELECT $a, $c;
+```
+
+``` yql
+$x, $y = AsTuple($y, $x); -- swap значений выражений
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/operators.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/operators.md
new file mode 100644
index 00000000000..fce85067c7a
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/operators.md
@@ -0,0 +1,87 @@
+## Операторы
+
+### Арифметические операторы {#math-operators}
+
+Операторы `+`, `-`, `*`, `/`, `%` определены для [примитивных типов данных](../../../types/primitive.md), являющихся разновидностями чисел.
+
+Для типа данных Decimal используется банковское округление (до ближайшего четного).
+
+**Примеры**
+
+``` yql
+SELECT 2 + 2;
+```
+
+``` yql
+SELECT 0.0 / 0.0;
+```
+
+### Операторы сравнения {#comparison-operators}
+
+Операторы `=`, `==`, `!=`, `<>`, `>`, `<` определены для:
+
+* Примитивных типов данных за исключением Yson и Json.
+* Кортежей и структур с одинаковым набором полей. Для структур не определен порядок, но можно проверять на (не-)равенство, а кортежи сравниваются поэлементно слева направо.
+
+**Примеры**
+
+``` yql
+SELECT 2 > 1;
+```
+
+### Логические операторы {#logic-operators}
+
+С помощью операторов `AND`, `OR`, `XOR` осуществляются логические операции над булевыми значениями (`Bool`).
+
+**Примеры**
+
+``` yql
+SELECT 3 > 0 AND false;
+```
+
+### Битовые операторы {#bit-operators}
+
+Битовые операции над числами:
+
+* `&`, `|`, `^` — AND, OR и XOR соответственно. Не следует путать битовые операции с аналогичными ключевыми словами. Ключевые слова `AND`, `OR` и `XOR` используются *только для булевых значений*, но не для чисел;
+* ` ~ ` — отрицание;
+* `<<`, `>>` — сдвиги влево-вправо;
+* `|<<`, `>>|` — кольцевые сдвиги влево-вправо.
+
+**Примеры**
+
+``` yql
+SELECT
+ key << 10 AS key,
+ ~value AS value
+FROM my_table;
+```
+
+### Приоритет и ассоциативность операторов {#operator-priority}
+
+Приоритет оператора определяет порядок вычисления выражения содержащего разные операторы.
+Например, выражение `1 + 2 * 3` вычисляется как `1 + (2 * 3)`,
+поскольку приоритет оператора умножения больше приоритета оператора сложения.
+
+Ассоциативность определяет порядок вычисления в выражениях содержащих операторы одного типа.
+Например, выражение `1 + 2 + 3` вычисляется как `(1 + 2) + 3`, поскольку оператор сложения является лево-ассоциативным.
+С другой стороны, выражение `a ?? b ?? c` вычисляется как `a ?? (b ?? c)` из-за право-ассоциативности оператора `??`
+
+В таблице ниже указаны приоритет и ассоциативность операторов языка YQL.
+Операторы в таблице перечислены в порядке убывания приоритета.
+
+| Приоритет | Оператор | Описание | Ассоциативность |
+| --- | --- | --- | --- |
+| 1 | <code>a[], a.foo, a()</code> | Обращение к элементу контейнера, вызов функции | Левая |
+| 2 | <code>+a, -a, ~a, NOT a</code> | Унарные операторы: плюс, минус, битовое и логическое отрицание | Правая |
+| 3 | <code>a &#124;&#124; b</code> | [Конкатенация строк](#concatenation) | Левая |
+| 4 | <code>a*b, a/b, a%b</code> | Умножение,деление, остаток от деления | Левая |
+| 5 | <code>a+b, a-b</code> | Сложение / вычитание | Левая |
+| 6 | <code>a ?? b</code> | Операторная форма записи [NVL/COALESCE](../../../builtins/basic.md#coalesce) | Правая |
+| 7 | <code>a<<b, a>>b, a&#124;<<b, a>>&#124;b,</code> <code>a&#124;b, a^b, a&b</code> | Сдвиговые и логические битовые операторы | Левая |
+| 8 | <code>a<b, a<=b, a>=b, a>b</code> | Сравнение | Левая |
+| 9 | <code>a IN b</code> | Вхождение элемента в множество | Левая |
+| 9 | <code>a==b, a=b, a!=b, a<>b,</code> <code>a is (not) distinct from b</code> | Сравнение на (не)равенство | Левая |
+| 10 | <code>a XOR b</code> | Логическое XOR | Левая |
+| 11 | <code>a AND b</code> | Логическое AND | Левая |
+| 12 | <code>a OR b</code> | Логическое OR | Левая |
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/tables.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/tables.md
new file mode 100644
index 00000000000..292d9f367a2
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/expressions/tables.md
@@ -0,0 +1,70 @@
+## Табличные выражения {#table-contexts}
+
+Табличное выражения – это выражение, которое возвращает таблицу. Табличными выражениями в YQL являются:
+* подзапросы: `(SELECT key, subkey FROM T)`
+* [именованные подзапросы](#named-nodes): `$foo = SELECT * FROM T;` (использование именованного подзапроса `$foo` является табличным выражением)
+{% if feature_subquery %}
+* [шаблоны подзапросов](../../subquery.md#define-subquery): `DEFINE SUBQUERY $foo($name) AS ... END DEFINE;` (вызов `$foo("InputTable")` является табличным выражением).
+{% endif %}
+
+Семантика табличного выражения зависит от контекста в котором оно используется. В YQL табличные выражения могут применяться в следующих контекстах:
+* табличный контекст - после [FROM](../../select.md#from).
+Здесь табличные выражения работают как ожидается – например `$input = SELECT a, b, c FROM T; SELECT * FROM $input` вернет таблицу с тремя колонками.
+Табличный контекст также возникает после [UNION ALL](../../select.md#unionall){% if feature_join %}, [JOIN](../../join.md#join){% endif %}{% if feature_mapreduce and process_command == "PROCESS" %}, [PROCESS](../../process.md#process), [REDUCE](../../reduce.md#reduce){% endif %};
+* векторный контекст - после [IN](#in). В этом контексте табличное выражение обязано содержать ровно одну колонку (имя этой колонки никак не влияет на результат выражения).
+Табличное выражение в векторном контексте типизируется как список (тип элемента списка при этом совпадает с типом колонки). Пример: `SELECT * FROM T WHERE key IN (SELECT k FROM T1)`;
+* скалярный контекст возникает _во всех остальных случаях_. Как и в векторном контексте,
+табличное выражение должно содержать ровно одну колонку, но значением табличного выражения будет скаляр –
+произвольно выбранное значение этой колонки (если получилось ноль строк, то результатом будет `NULL`). Пример: `$count = SELECT COUNT(*) FROM T; SELECT * FROM T ORDER BY key LIMIT $count / 2`;
+
+Порядок строк в табличном контексте, порядок элементов в векторном контексте и правило выбора значения в скалярном контексте (в случае если значений несколько) не определены. На этот порядок также нельзя повлиять с помощью `ORDER BY`: `ORDER BY` без `LIMIT` в табличных выражениях будет игнорироваться с выдачей предупреждения, а использование `ORDER BY` с `LIMIT` определяет множество элементов, но не порядок внутри этого множества.
+
+{% if feature_mapreduce and process_command == "PROCESS" %}
+
+Из этого правила есть исключение. Именованное выражение с [PROCESS](../../process.md#process), будучи использованным в скалярном контексте, ведет себя как в табличном:
+
+```yql
+$input = SELECT 1 AS key, 2 AS value;
+$process = PROCESS $input;
+
+SELECT FormatType(TypeOf($process)); -- $process используется в скалярном контексте,
+ -- но результат SELECT при этом - List<Struct<'key':Int32,'value':Int32>>
+
+SELECT $process[0].key; -- вернет 1
+
+SELECT FormatType(TypeOf($input)); -- ошибка: $input в скалярном контексте должен содержать одну колонку
+```
+{% note warning "Внимание" %}
+
+Часто встречающейся ошибкой является использование выражения в скалярном контексте вместо табличного или векторного. Например:
+
+```yql
+$dict = SELECT key, value FROM T1;
+
+DEFINE SUBQUERY $merge_dict($table, $dict) AS
+SELECT * FROM $table LEFT JOIN $dict USING(key);
+END DEFINE;
+
+SELECT * FROM $merge_dict("Input", $dict); -- $dict здесь используется в скалярном контексте.
+ -- ошибка - в скалярном контексте ожидается ровно одна колонка
+
+```
+
+Правильное решение в данном случае выглядит так:
+
+```yql
+DEFINE SUBQUERY $dict() AS
+SELECT key, value FROM T1;
+END DEFINE;
+
+DEFINE SUBQUERY $merge_dict($table, $dict) AS
+SELECT * FROM $table LEFT JOIN $dict() USING(key); -- использование табличного выражения $dict()
+ -- (вызов шаблона подзапроса) в табличном контексте
+END DEFINE;
+
+SELECT * FROM $merge_dict("Input", $dict); -- $dict - шаблон позапроса (не табличное выражение)
+ -- передаваемый в качестве аргумента табличного выражения
+```
+
+{% endnote %}
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_by.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_by.md
new file mode 100644
index 00000000000..e5e4ffc6baa
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_by.md
@@ -0,0 +1,68 @@
+# FLATTEN
+
+## FLATTEN BY {#flatten-by}
+
+Преобразует строки исходной таблицы с помощью вертикального разворачивания [контейнеров](../../../types/containers.md) переменной длины (списков или словарей).
+
+Например:
+
+* Исходная таблица:
+ |[a, b, c]|1|
+ | --- | --- |
+ |[d]|2|
+ |[]|3|
+
+* Таблица после вызова `FLATTEN BY` к левому столбцу:
+ |a|1|
+ | --- | --- |
+ |b|1|
+ |c|1|
+ |d|2|
+
+{% if feature_column_container_type != true %}
+
+В таблицах {{ backend_name }} не поддерживаются контейнерные типы, поэтому функция FLATTEN BY может применяться только над переменными табличных типов, создаваемых в рамках YQL запроса.
+
+{% endif %}
+
+**Пример**
+```(sql)
+$sample = AsList(
+ AsStruct(AsList('a','b','c') AS value, CAST(1 AS Uint32) AS id),
+ AsStruct(AsList('d') AS value, CAST(2 AS Uint32) AS id),
+ AsStruct(AsList() AS value, CAST(3 AS Uint32) AS id)
+);
+
+SELECT value, id FROM as_table($sample) FLATTEN BY (value);
+```
+
+Такое преобразование может быть удобным в следующих случаях:
+* Когда по ячейкам из столбца-контейнера необходимо вывести статистику (например, через [`GROUP BY`](../../group_by.md)).
+{% if feature_join %}
+* Когда в ячейках столбца-контейнера хранятся идентификаторы из другой таблицы, которую нужно присоединить с помощью [`JOIN`](../../join.md).
+{% endif %}
+
+**Синтаксис**
+
+* `FLATTEN BY` указывается после `FROM`, но перед `GROUP BY`, если `GROUP BY` присутствует в запросе.
+* Тип столбца-результата зависит от типа исходного столбца:
+
+| Тип контейнера | Тип результата | Комментарий |
+| --- | --- | --- |
+| `List<X>` | `X` | Тип ячейки списка |
+| `Dict<X,Y>` | `Tuple<X,Y>` | Кортеж из двух элементов с парами «ключ—значение» |
+| `Optional<X>` | `X` | Результат практически эквивалентен конструкции `WHERE foo IS NOT NULL`, но тип колонки `foo` будет изменен на `X`|
+
+* По умолчанию столбец с результатом заменяет исходный. Используйте `FLATTEN BY foo AS bar` для сохранения исходного контейнера. В результате исходный контейнер останется доступным в `foo`, а построенный — в `bar`.
+* Чтобы построить декартово произведение нескольких столбцов-контейнеров, используйте конструкцию `FLATTEN BY (a, b, c)`. Скобки обязательны, чтобы избежать конфликтов в грамматике.
+* В `FLATTEN BY` можно использовать только имена столбцов из входной таблицы. Чтобы применить `FLATTEN BY` к результату вычисления, используйте подзапрос.
+* В `FLATTEN BY ` можно использовать не только столбцы, но и произвольные именованные выражения (в отличие от столбцов `AS` обязательно). Из-за грамматических неоднозначностей выражения после `FLATTEN BY` должны быть заключены в скобки: `... FLATTEN BY (ListSkip(col, 1) AS col) ...`
+* Если в исходном столбце были вложенные контейнеры, например `List<Dict<X,Y>>`, `FLATTEN BY` развернет только внешний уровень. Чтобы полностью развернуть вложенные контейнеры, используйте подзапрос.
+
+{% note info %}
+
+`FLATTEN BY` интерпретирует [опциональные типы данных](../../../types/optional.md) как списки длины 0 или 1. Строки таблицы с `NULL` пропускаются, и тип столбца меняется на аналогичный неопциональный.
+
+`FLATTEN BY` делает только одно преобразование за раз, поэтому на опциональных контейнерах, например, `Optional<List<String>>` следует использовать `FLATTEN LIST BY` или `FLATTEN OPTIONAL BY`.
+
+{% endnote %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_columns.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_columns.md
new file mode 100644
index 00000000000..7e7338de773
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_columns.md
@@ -0,0 +1,19 @@
+## FLATTEN COLUMNS {#flatten-columns}
+
+Преобразует таблицу, в которой все столбцы должны являться структурами, в таблицу со столбцами, соответствующими каждому элементу каждой структуры из исходных столбцов.
+
+Имена исходных столбцов-структур не используются и не возвращаются в результате. Имена элементов структур не должны повторяться в исходных столбцах.
+
+**Пример**
+
+```sql
+SELECT x, y, z
+FROM (
+ SELECT
+ AsStruct(
+ 1 AS x,
+ "foo" AS y),
+ AsStruct(
+ false AS z)
+) FLATTEN COLUMNS;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_other_db.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_other_db.md
new file mode 100644
index 00000000000..104d7e51a4f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_other_db.md
@@ -0,0 +1,9 @@
+### Аналоги FLATTEN BY для других СУБД {#flatten-other-dmb}
+
+* PostgreSQL: `unnest`;
+* Hive: `LATERAL VIEW`;
+* MongoDB: `unwind`;
+* Google BigQuery: `FLATTEN`;
+* ClickHouse: `ARRAY JOIN / arrayJoin`;
+
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_type_by.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_type_by.md
new file mode 100644
index 00000000000..8a391dc261f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/flatten/flatten_type_by.md
@@ -0,0 +1,41 @@
+### Уточнение типа контейнера {#flatten-by-specific-type}
+
+Чтобы уточнить тип контейнера, по которому необходимо произвести преобразование, можно использовать:
+
+* `FLATTEN LIST BY`
+
+ Для `Optional<List<T>>` операция `FLATTEN LIST BY` будет разворачивать список, интерпретируя `NULL`-значение как пустой список.
+* `FLATTEN DICT BY`
+
+ Для `Optional<Dict<T>>` операция `FLATTEN DICT BY` будет разворачивать словарь, интерпретируя `NULL`-значение как пустой словарь.
+* `FLATTEN OPTIONAL BY`
+
+ Чтобы фильтровать `NULL`-значения без размножения, необходимо уточнить операцию до `FLATTEN OPTIONAL BY`.
+
+**Примеры**
+
+```sql
+SELECT
+ t.item.0 AS key,
+ t.item.1 AS value,
+ t.dict_column AS original_dict,
+ t.other_column AS other
+FROM my_table AS t
+FLATTEN DICT BY dict_column AS item;
+```
+
+```sql
+SELECT * FROM (
+ SELECT
+ AsList(1, 2, 3) AS a,
+ AsList("x", "y", "z") AS b
+) FLATTEN LIST BY (a, b);
+```
+
+``` yql
+SELECT * FROM (
+ SELECT
+ "1;2;3" AS a,
+ AsList("x", "y", "z") AS b
+) FLATTEN LIST BY (String::SplitToList(a, ";") as a, b);
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md
new file mode 100644
index 00000000000..3ebdf0a1980
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/compact.md
@@ -0,0 +1,16 @@
+## GROUP COMPACT BY
+
+Позволяет более эффективно выполнять агрегацию в тех случаях, когда автору запроса заранее известно, что ни по одному из ключей агрегации не встречаются большие объемы данных (больше примерно гигабайт или миллионов строк). Если это предположение на практике окажется неверным, то операция оставляет за собой право упасть из-за превышения потребления оперативной памяти или работать значительно медленнее не-COMPACT версии.
+
+В отличие от обычного GROUP BY, отключается стадия Map-side combiner и дополнительные Reduce для каждого поля с [DISTINCT](#distinct) агрегацией.
+
+**Пример:**
+``` yql
+SELECT
+ key,
+ COUNT(DISTINCT value) AS count -- топ-3 ключей по количеству уникальных значений
+FROM my_table
+GROUP COMPACT BY key
+ORDER BY count DESC
+LIMIT 3;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/distinct.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/distinct.md
new file mode 100644
index 00000000000..dcb3ec18ddd
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/distinct.md
@@ -0,0 +1,24 @@
+## DISTINCT {#distinct}
+
+Применение [агрегатных функций](../../../builtins/aggregation.md) только к уникальным значениям столбца.
+
+{% note info %}
+
+Применение `DISTINCT` к вычислимым значениям на данный момент не реализовано. С этой целью можно использовать [подзапрос](../../select.md#from) или выражение `GROUP BY ... AS ...`.
+
+{% endnote %}
+
+**Пример**
+
+```sql
+SELECT
+ key,
+ COUNT(DISTINCT value) AS count -- топ-3 ключей по количеству уникальных значений
+FROM my_table
+GROUP BY key
+ORDER BY count DESC
+LIMIT 3;
+```
+
+Также ключевое слово `DISTINCT` может использоваться для выборки уникальных строк через [`SELECT DISTINCT`](../../select.md#distinct).
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/general.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/general.md
new file mode 100644
index 00000000000..de0aac04bb6
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/general.md
@@ -0,0 +1,67 @@
+## GROUP BY
+
+Группирует результаты `SELECT` по значениям указанных столбцов или выражений. Вместе с `GROUP BY` часто применяются [агрегатные функции](../../../builtins/aggregation.md) (`COUNT`, `MAX`, `MIN`, `SUM`, `AVG`) для выполнения вычислений в каждой группе.
+
+**Синтаксис**
+```sql
+SELECT -- В SELECT можно использовать:
+ column1, -- ключевые колонки, заданные в GROUP BY
+ key_n, -- именованные выражения, заданные в GROUP BY
+ column1 + key_n, -- произвольные неагрегатные функции от них
+ Aggr_Func1( column2 ), -- агрегатные функции, содержащие в аргументах любые колонки,
+ Aggr_Func2( key_n + column2 ), -- включая именованные выражения, заданные в GROUP BY
+ ...
+FROM table
+GROUP BY
+ column1, column2, ...,
+ <expr> AS key_n -- При группировке по выражению ему может быть задано имя через AS,
+ -- которое может быть использовано в SELECT
+```
+
+Запрос вида `SELECT * FROM table GROUP BY k1, k2, ...` вернет все колонки, перечисленные в GROUP BY, то есть экивалентент запросу `SELECT DISTINCT k1, k2, ... FROM table`.
+
+Звездочка может также применяться в качестве аргумента агрегатной функции `COUNT`. `COUNT(*)` означает "число строк в группе".
+
+
+{% note info %}
+
+Агрегатные функции не учитывают `NULL` в своих аргументах, за исключением функции `COUNT`.
+
+{% endnote %}
+
+Также в YQL доступен механизм фабрик агрегатных функций, реализованный с помощью функций [`AGGREGATION_FACTORY`](../../../builtins/basic.md#aggregationfactory) и [`AGGREGATE_BY`](../../../builtins/aggregation.md#aggregateby).
+
+**Примеры**
+
+```sql
+SELECT key, COUNT(*) FROM my_table
+GROUP BY key;
+```
+
+```sql
+SELECT double_key, COUNT(*) FROM my_table
+GROUP BY key + key AS double_key;
+```
+
+```sql
+SELECT
+ double_key, -- ОК: ключевая колонка
+ COUNT(*) AS group_size, -- OK: COUNT(*)
+ SUM(key + subkey) AS sum1, -- ОК: агрегатная функция
+ CAST(SUM(1 + 2) AS String) AS sum2, -- ОК: агрегатная функция с константным аргументом
+ SUM(SUM(1) + key) AS sum3, -- ОШИБКА: вложенные агрегации не допускаются
+ key AS k1, -- ОШИБКА: использование неключевой колонки key без агрегации
+ key * 2 AS dk1, -- ОШИБКА в YQL: использование неключевой колонки key без агрегации
+FROM my_table
+GROUP BY
+ key * 2 AS double_key,
+ subkey as sk,
+
+```
+
+
+{% note warning "Внимание" %}
+
+Возможность указывать имя для колонки или выражения в `GROUP BY .. AS foo` является расширением YQL. Такое имя становится видимым в `WHERE` несмотря на то, что фильтрация по `WHERE` выполняется [раньше](../../select.md#selectexec) группировки. В частности, если в таблице `T` есть две колонки `foo` и `bar`, то в запросе `SELECT foo FROM T WHERE foo > 0 GROUP BY bar AS foo` фильтрация фактически произойдет по колонке `bar` из исходной таблицы.
+
+{% endnote %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/general_stream.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/general_stream.md
new file mode 100644
index 00000000000..2b5b4b02551
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/general_stream.md
@@ -0,0 +1,55 @@
+## GROUP BY ... HOP
+
+Сгруппировать таблицу по значениям указанных столбцов или выражений, а также окну времени.
+
+Если GROUP BY присутствует в запросе, то при выборке столбцов (между `SELECT STREAM ... FROM`) допустимы **только** следующие конструкции:
+
+1. Столбцы, по которым производится группировка (присутствующие в аргументе `GROUP BY`).
+2. Агрегатные функции (см. следующий раздел). Столбцы, по которым **не** идет группировка, можно включать только в качестве аргументов агрегатной функции.
+3. Функции, выдающие начальное и конечное время текущего окна (`HOP_START` и `HOP_END`)
+4. Произвольные вычисления, комбинирующие пункты 1-3.
+
+Имеется возможность выполнять группировку по результату вычисления произвольного выражения от исходных столбцов. В этом случае для получения доступа к результату этого выражения рекомендуется присваивать ему имя с помощью `AS`, см. второй пример.
+
+Агрегатные функции автоматически пропускают `NULL` в своих аргументах.
+
+Среди столбцов, по которым производится группировка, должна присутствовать конструкция `HOP`, определяющая характеристики окна времени для группировки.
+``` yql
+HOP(time_extractor, hop, interval, delay)
+```
+Реализованный вариант окна времени называется **hopping window**. Это окно, продвигающееся вперёд дискретными интервалами (параметр `hop`). Общая длительность окна задаётся параметром `interval`. Для определения времени каждого входного события используется параметр `time_extractor`. Это выражение, зависящее только от входных значений столбцов стрима, должно иметь тип `Timestamp`. Оно указывает, откуда именно во входных событиях доставать значение времени.
+
+В каждом потоке, определяемом значениями всех столбцов группировки, окно продвигается независимо от других потоков. Продвижение окна полностью зависит от самого позднего события потока. Поскольку записи в потоках слегка перемешиваются во времени, добавлен параметр `delay`, позволяющий отложить закрытие окна на указанную величину. События, приходящие до текущего окна, игнорируются.
+
+Параметры `interval` и `delay` следует задавать кратными параметру `hop`. Некратные интервалы будут округлены в меньшую сторону.
+
+Для задания `hop`, `interval` и `delay` используется строковое выражение, соответствующее стандарту [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601). Это формат, который используется для конструирования встроенного типа `Interval` [из строки](../../../builtins/basic.md#data-type-literals).
+
+Функции без параметров `HOP_START` и `HOP_END` возвращают значение типа `Timestamp` и соответствуют началу и концу текущего окна.
+
+Известное в других системах **tumbling window** является частным случаем **hopping window**, когда `interval` == `hop`.
+
+**Примеры:**
+``` yql
+SELECT STREAM
+ key,
+ COUNT(*)
+FROM my_stream
+GROUP BY
+ HOP(CAST(subkey AS Timestamp), "PT10S", "PT1M", "PT30S"),
+ key;
+-- hop = 10 секунд
+-- interval = 1 минута
+-- delay = 30 секунд
+```
+
+``` yql
+SELECT STREAM
+ double_key,
+ HOP_END() as time,
+ COUNT(*) as count
+FROM my_stream
+GROUP BY
+ key + key AS double_key,
+ HOP(ts, "PT1М", "PT1M", "PT1M");
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/having.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/having.md
new file mode 100644
index 00000000000..76611be253e
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/having.md
@@ -0,0 +1,13 @@
+## HAVING {#having}
+
+Фильтрация выборки `SELECT` по результатам вычисления [агрегатных функций](../../../builtins/aggregation.md). Синтаксис аналогичен конструкции [`WHERE`](../../select.md#where).
+
+**Пример**
+
+``` yql
+SELECT
+ key
+FROM my_table
+GROUP BY key
+HAVING COUNT(value) > 100;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/having_stream.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/having_stream.md
new file mode 100644
index 00000000000..2eb4a7c4a80
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/having_stream.md
@@ -0,0 +1,12 @@
+## HAVING {#having}
+
+Фильтрация выборки `SELECT STREAM` по результатам вычисления [агрегатных функций](../../../builtins/aggregation.md). Синтаксис аналогичен [WHERE](../../select_stream.md#where).
+
+**Примеры:**
+``` yql
+SELECT STREAM
+ key
+FROM my_table
+GROUP BY key, HOP(ts, "PT1M", "PT1M", "PT1M")
+HAVING COUNT(value) > 100;
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/rollup_cube_sets.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/rollup_cube_sets.md
new file mode 100644
index 00000000000..7baa2e42186
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/rollup_cube_sets.md
@@ -0,0 +1,75 @@
+## ROLLUP, CUBE и GROUPING SETS {#rollup}
+
+Результаты вычисления агрегатной функции в виде промежуточных итогов для групп и общих итогов для отдельных столбцов или всей таблицы.
+
+**Синтаксис**
+
+```sql
+SELECT
+ c1, c2, -- столбцы, по которым производится группировка
+
+AGGREGATE_FUNCTION(c3) AS outcome_c -- агрегатная функция (SUM, AVG, MIN, MAX, COUNT)
+
+FROM table_name
+
+GROUP BY
+ GROUP_BY_EXTENSION(c1, c2) -- расширение GROUP BY: ROLLUP, CUBE или GROUPING SETS
+```
+
+
+* `ROLLUP` — группирует значения столбцов в порядке их перечисления в аргументах (строго слева направо), формирует промежуточные итоги для каждой группы и общий итог.
+* `CUBE` — группирует значения для всех возможных комбинаций столбцов, формирует промежуточные итоги для каждой группы и общий итог.
+* `GROUPING SETS` — задает группы для промежуточных итогов.
+
+`ROLLUP`, `CUBE` и `GROUPING SETS` можно комбинировать через запятую.
+
+### GROUPING {#grouping}
+
+В промежуточном итоге значения столбцов, которые не участвуют в вычислениях, заменяются на `NULL`. В общем итоге на `NULL` заменяются значения всех столбцов. `GROUPING` — функция, которая позволяет отличить исходные значения `NULL` от `NULL`, которые были добавлены при формировании общих и промежуточных итогов.
+
+`GROUPING` возвращает битовую маску:
+* `0` — `NULL` для исходного пустого значения.
+* `1` — `NULL`, добавленный для промежуточного или общего итога.
+
+**Пример**
+
+```sql
+SELECT
+ column1,
+ column2,
+ column3,
+
+ CASE GROUPING(
+ column1,
+ column2,
+ column3,
+ )
+ WHEN 1 THEN "Subtotal: column1 and column2"
+ WHEN 3 THEN "Subtotal: column1"
+ WHEN 4 THEN "Subtotal: column2 and column3"
+ WHEN 6 THEN "Subtotal: column3"
+ WHEN 7 THEN "Grand total"
+ ELSE "Individual group"
+ END AS subtotal,
+
+ COUNT(*) AS rows_count
+
+FROM my_table
+
+GROUP BY
+ ROLLUP(
+ column1,
+ column2,
+ column3
+ ),
+ GROUPING SETS(
+ (column2, column3),
+ (column3)
+ -- если добавить сюда ещё (column2), то в сумме
+ -- эти ROLLUP и GROUPING SETS дали бы результат,
+ -- аналогичный CUBE
+ )
+;
+```
+
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/session_window.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/session_window.md
new file mode 100644
index 00000000000..cccff86f6d2
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/group_by/session_window.md
@@ -0,0 +1,63 @@
+## GROUP BY ... SessionWindow() {#session-window}
+
+В YQL поддерживаются группировки по сессиям. К обычным выражениям в `GROUP BY` можно добавить специальную функцию `SessionWindow`:
+
+```sql
+SELECT
+ user,
+ session_start,
+ SessionStart() AS same_session_start, -- то же что и session_start
+ COUNT(*) AS session_size,
+ SUM(value) AS sum_over_session,
+FROM my_table
+GROUP BY user, SessionWindow(<time_expr>, <timeout_expr>) AS session_start
+```
+
+При этом происходит следующее:
+
+1) Входная таблица партиционируется по ключам группировки, указанным в `GROUP BY`, без учета SessionWindow (в данном случае по `user`).
+ Если кроме SessionWindow в `GROUP BY` ничего нет, то входная таблица попадает в одну партицию
+2) Каждая партиция делится на непересекающие подмножества строк (сессии).
+ Для этого партиция сортируется по возрастанию значения выражения `time_expr`.
+ Границы сессий проводятся между соседними элементами партиции, разница значений `time_expr` для которых превышает `timeout_expr`
+3) Полученные таким образом сессии и являются финальными партициями, на которых вычисляются агрегатные функции.
+
+Ключевая колонка SessionWindow() (в примере `session_start`) имеет значение "минимальный `time_expr` в сессии".
+Кроме того, при наличии SessionWindow() в `GROUP BY` может использоваться специальная агрегатная функция
+[SessionStart](../../../builtins/aggregation.md#session-start).
+
+Поддерживается также расширенный вариант SessionWindow с четырьмя аргументами:
+
+`SessionWindow(<order_expr>, <init_lambda>, <update_lambda>, <calculate_lambda>)`
+
+Здесь:
+* `<order_expr>` – выражение по которому сортируется исходная партиция
+* `<init_lambda>` – лямбда-функция для инициализации состояния расчета сессий. Имеет сигнатуру `(TableRow())->State`. Вызывается один раз на первом (по порядку сортировки) элементе исходной партиции
+* `<update_lambda>` – лямбда-функция для обновления состояния расчета сессий и определения границ сессий. Имеет сигнатуру `(TableRow(), State)->Tuple<Bool, State>`. Вызывается на каждом элементе исходной партиции, кроме первого. Новое значения состояния вычисляется на основе текущей строки таблицы и предыдущего состояния. Если первый элемент возвращенного кортежа имеет значение `True`, то с _текущей_ строки начнется новая сессия. Ключ новой сессии получается путем применения `<calculate_lambda>` ко второму элементу кортежа.
+* `<calculate_lambda>` – лямбда-функция для вычисления ключа сессии ("значения" SessionWindow(), которое также доступно через SessionStart()). Функция имеет сигнатуру `(TableRow(), State)->SessionKey`. Вызывается на первом элемента партиции (после `<init_lambda>`) и на тех элементах, для которых `<update_lambda>` вернула `True` в качестве первого элемента кортежа. Стоит отметить, что для начала новой сессии необходимо, чтобы `<calculate_lambda>` вернула значение, которое отличается от предыдущего ключа сессии. При этом сессии с одинаковыми ключами не объединяются. Например, если `<calculate_lambda>` последовательно возвращает `0, 1, 0, 1`, то это будут четыре различные сессии.
+
+С помощью расширенного варианта SessionWindow можно решить, например, такую задачу: разделить партицию на сессии как в варианте SessionWindow с двумя аргументами, но с ограничением максимальной длины сессии некоторой константой:
+
+**Пример**
+```sql
+$max_len = 1000; -- максимальная длина сессии
+$timeout = 100; -- таймаут (timeout_expr в упрощенном варианте SessionWindow)
+
+$init = ($row) -> (AsTuple($row.ts, $row.ts)); -- состояние сессии - тапл из 1) значения временной колонки ts на первой строчке сессии и 2) на текущей строчке
+$update = ($row, $state) -> {
+ $is_end_session = $row.ts - $state.0 > $max_len OR $row.ts - $state.1 > $timeout;
+ $new_state = AsTuple(IF($is_end_session, $row.ts, $state.0), $row.ts);
+ return AsTuple($is_end_session, $new_state);
+};
+$calculate = ($row, $state) -> ($row.ts);
+SELECT
+ user,
+ session_start,
+ SessionStart() AS same_session_start, -- то же что и session_start
+ COUNT(*) AS session_size,
+ SUM(value) AS sum_over_session,
+FROM my_table
+GROUP BY user, SessionWindow(ts, $init, $update, $calculate) AS session_start
+```
+
+SessionWindow может использоваться в GROUP BY только один раз.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/insert_hints.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/insert_hints.md
new file mode 100644
index 00000000000..52b853f0576
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/insert_hints.md
@@ -0,0 +1,16 @@
+{% if feature_insert_with_truncate %}
+
+Запись может выполняться с одним или несколькими модификаторами. Модификатор указывается после ключевого слова `WITH` после имени таблицы: `INSERT INTO ... WITH SOME_HINT`.
+Если у модификатора есть значение, то оно указывается после знака `=`: `INSERT INTO ... WITH SOME_HINT=value`.
+При необходимости указать несколько модификаторов они должны заключаться в круглые скобки: `INSERT INTO ... WITH (SOME_HINT1=value, SOME_HINT2, SOME_HINT3=value)`.
+
+Чтобы перед записью очистить таблицу от имевшихся данных достаточно добавить модификатор: `INSERT INTO ... WITH TRUNCATE`.
+
+**Примеры:**
+
+``` yql
+INSERT INTO my_table WITH TRUNCATE
+SELECT key FROM my_table_source;
+```
+
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/insert_into.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/insert_into.md
new file mode 100644
index 00000000000..39c9658a04f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/insert_into.md
@@ -0,0 +1,47 @@
+# INSERT INTO
+{% if select_command != "SELECT STREAM" %}
+Добавляет строки в таблицу. {% if feature_bulk_tables %} Если целевая таблица уже существует и не является сортированной, операция `INSERT INTO` дописывает строки в конец таблицы. В случае сортированной таблицы, YQL пытается сохранить сортированность путем запуска сортированного слияния. {% endif %}{% if feature_map_tables %} При попытке вставить в таблицу строку с уже существующим значением первичного ключа операция завершится ошибкой с кодом `PRECONDITION_FAILED` и текстом `Operation aborted due to constraint violation: insert_pk`.{% endif %}
+
+{% if feature_mapreduce %}Таблица по имени ищется в базе данных, заданной оператором [USE](../use.md).{% endif %}
+
+`INSERT INTO` позволяет выполнять следующие операции:
+
+* Добавление константных значений с помощью [`VALUES`](../values.md).
+
+ ```sql
+ INSERT INTO my_table (Key1, Key2, Value1, Value2)
+ VALUES (345987,'ydb', 'Яблочный край', 1414);
+ COMMIT;
+ ```
+
+ ``` sql
+ INSERT INTO my_table (key, value)
+ VALUES ("foo", 1), ("bar", 2);
+ ```
+
+* Сохранение результата выборки `SELECT`.
+
+ ```sql
+ INSERT INTO my_table
+ SELECT Key AS Key1, "Empty" AS Key2, Value AS Value1
+ FROM my_table1;
+ ```
+
+{% else %}
+
+Направить результат вычисления [SELECT STREAM](../select_stream.md) в указанный стрим на кластере, заданном оператором [USE](../use.md). Стрим должен существовать и иметь схему, подходящую результату запроса.
+
+**Примеры:**
+``` yql
+INSERT INTO my_stream_dst
+SELECT STREAM key FROM my_stream_src;
+```
+
+Существует возможность указать в качестве цели таблицу на кластере ydb. Таблица должна существовать на момент создания операции. Схема таблицы должна быть совместима с типом результата запроса.
+
+**Примеры:**
+``` yql
+INSERT INTO ydb_cluster.`my_table_dst`
+SELECT STREAM * FROM rtmr_cluster.`my_stream_source`;
+```
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/into_result.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/into_result.md
new file mode 100644
index 00000000000..5872f817347
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/into_result.md
@@ -0,0 +1,16 @@
+# INTO RESULT
+
+Позволяет задать пользовательскую метку для [SELECT](../select.md){% if feature_mapreduce and process_command == "PROCESS" %}, [PROCESS](../process.md) или [REDUCE](../reduce.md){% endif %}. Не может быть задано одновременно с [DISCARD](../discard.md).
+
+**Примеры:**
+
+``` yql
+SELECT 1 INTO RESULT foo;
+```
+
+``` yql
+SELECT * FROM
+my_table
+WHERE value % 2 == 0
+INTO RESULT `Название результата`;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/join.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/join.md
new file mode 100644
index 00000000000..11210b88898
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/join.md
@@ -0,0 +1,130 @@
+# JOIN
+
+Позволяет объединить несколько источников данных (подзапросов или таблиц) по равенству значений указанных столбцов или выражений (ключей `JOIN`).
+
+**Синтаксис**
+
+``` sql
+SELECT ... FROM table_1
+-- первый шаг объединения:
+ <Join_Type> JOIN table_2 <Join_Condition>
+ -- исходная выборка -- записи в таблице table_1
+ -- присоединяемая выборка -- записи в таблице table_2
+-- следующий шаг объединения:
+ <Join_Type> JOIN table_n <Join_Condition>
+ -- исходная выборка -- результат объединения на предыдущем шаге
+ -- присоединяемая выборка -- записи в таблице table_n
+-- могут быть следующие шаги объединения
+...
+WHERE ...
+```
+
+На каждом шаге объединения по заданным правилам определяются соответствия между строками исходной и присоединяемой выборок данных, и формируется новая выборка, в которую попадают все сочетания подошедших под условия объединения строк.
+
+{% note warning "Внимание" %}
+
+Так как колонки в YQL идентифицируются по именам, и в выборке не может быть двух колонок с одинаковыми именами, `SELECT * FROM ... JOIN ...` не может быть исполнен при наличии колонок с одинаковыми именами в объединяемых таблицах.
+
+{% endnote %}
+
+
+## Типы объединения (Join_Type)
+
+* `INNER` <span style="color: gray;">(по умолчанию)</span> — Строки объединяемых выборок, для которых не найдено соответствие ни с одной строкой с другой стороны, не попадут в результат.
+* `LEFT` - При отсутствии значения в присоединяемой выборке включает строку в результат со значениям колонок из исходной выборки, оставляя пустыми (`NULL`) колонки присоединяемой выборки
+* `RIGHT` - При отсутствии значения в исходной выборке включает строку в результат со значениям колонок из присоединяемой выборки, оставляя пустыми (`NULL`) колонки исходной выборки
+* `FULL` = `LEFT` + `RIGHT`
+* `LEFT/RIGHT SEMI` — одна сторона выступает как белый список (whitelist) ключей, её значения недоступны. В результат включаются столбцы только из одной таблицы, декартового произведения не возникает;
+* `LEFT/RIGHT ONLY` — вычитание множеств по ключам (blacklist). Практически эквивалентно добавлению условия `IS NULL` на ключ противоположной стороны в обычном `LEFT/RIGHT`, но, как и в `SEMI`, нет доступа к значениям;
+* `CROSS` — декартово произведение двух таблиц целиком без указания ключевых колонок, секция с `ON/USING` явно не пишется;
+* `EXCLUSION` — обе стороны минус пересечение.
+
+![](../_assets/join-YQL-06.png)
+
+{% note info "Примечание" %}
+
+`NULL` является особым значением, которое ничему не равно. Таким образом, `NULL` с двух сторон **НЕ** считаются равными друг другу. Это избавляет от неоднозначности в некоторых типах `JOIN`, а также от гигантского декартового произведения, которое часто возникает в противном случае.
+
+{% endnote %}
+
+## Условия объединения (Join_Condition)
+
+Для `CROSS JOIN` условие объединения не указывается. В результат попадет декартово произведение исходной и присоединяемой выборкок, то есть сочетание всех со всеми. Количество строк в результирующей выборке будет произведением количества строк исходной и присоединяемой выборок.
+
+Для любых других типов объединения необходимо указать условие одним из двух способов:
+
+1. `USING (column_name)`. Используется при наличии в исходной и присоединяемой выборках одноименной колонки, равенство значений в которой является условием объединения.
+2. `ON (equality_conditions)`. Позволяет задать условие равенства значений колонок или выражений над колонками исходной и присоединяемой выборок, или несколько таких условий, объединенных по `and`.
+
+**Примеры:**
+``` sql
+SELECT a.value as a_value, b.value as b_value
+FROM a_table AS a
+FULL JOIN b_table AS b USING (key);
+```
+
+``` sql
+SELECT a.value as a_value, b.value as b_value
+FROM a_table AS a
+FULL JOIN b_table AS b ON a.key = b.key;
+```
+
+``` sql
+SELECT a.value as a_value, b.value as b_value, c.column2
+FROM a_table AS a
+CROSS JOIN b_table AS b
+LEFT JOIN c_table AS c ON c.ref = a.key and c.column1 = b.value;
+```
+
+{% if feature_mapreduce %}
+Если в выражении помимо `JOIN` выполняется фильтрация данных, то рекомендуется обернуть те условия, про которые известно, что они вернут `true` для большинства строк, в вызов функции `LIKELY(...)`. Если предположение о преобладании положительных значений в условии окажется верно, такая подсказка может положительно сказаться на времени выполнения запроса. Также `LIKELY` может быть полезен в том случае, когда вычисление предиката ресурсоёмко и при этом сам JOIN значительно сокращает число строк.
+
+Перед любым источником данных для `JOIN` можно указать ключевое слово `ANY`, которое служит для подавления дубликатов по ключам `JOIN` с соответствующей стороны. В этом случае из множества строк с одинаковым значением ключей `JOIN` остается только одна (не уточняется какая именно – отсюда и название `ANY`).
+Данный синтаксис отличается от принятого в [ClickHouse]{% if lang == "en" %}(https://clickhouse.com/docs/en/sql-reference/statements/select/join/){% endif %}{% if lang == "ru" %}(https://clickhouse.tech/docs/ru/sql-reference/statements/select/join/){% endif %}, где `ANY` пишется перед типом `JOIN` и работает только для правой стороны.
+
+Запрос
+
+``` yql
+$t1 = AsList(
+ AsStruct("1" AS key, "v111" AS value),
+ AsStruct("2" AS key, "v121" AS value),
+ AsStruct("2" AS key, "v122" AS value),
+ AsStruct("3" AS key, "v131" AS value),
+ AsStruct("3" AS key, "v132" AS value));
+
+$t2 = AsList(
+ AsStruct("2" AS key, "v221" AS value),
+ AsStruct("2" AS key, "v222" AS value),
+ AsStruct("3" AS key, "v231" AS value),
+ AsStruct("3" AS key, "v232" AS value),
+ AsStruct("4" AS key, "v241" AS value));
+
+SELECT
+ a.key, a.value, b.value
+FROM ANY AS_TABLE($t1) AS a
+JOIN ANY AS_TABLE($t2) AS b
+ON a.key == b.key;
+```
+
+выдаст:
+
+|a.key|a.value|b.value|
+| --- | --- | --- |
+|"3"|"v131"|"v231"|
+|"2"|"v121"|"v221"|
+
+
+а без `ANY` выдал бы:
+
+|a.key|a.value|b.value|
+| --- | --- | --- |
+|"3"|"v131"|"v231"|
+|"3"|"v131"|"v232"|
+|"3"|"v132"|"v231"|
+|"3"|"v132"|"v232"|
+|"2"|"v121"|"v221"|
+|"2"|"v121"|"v222"|
+|"2"|"v122"|"v221"|
+|"2"|"v122"|"v222"|
+
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/lexer.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/lexer.md
new file mode 100644
index 00000000000..3bd229141f1
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/lexer.md
@@ -0,0 +1,155 @@
+
+# Лексическая структура
+
+{% if feature_mapreduce %}Программа {% else %}Запрос {% endif %} на языке YQL представляет собой валидный UTF-8 текст, который состоит из _команд_ (statement) разделенных символом точка с запятой (`;`).
+Последняя точка с запятой при этом может отсутствовать.
+Каждая команда, в свою очередь, состоит из последовательности _токенов_ допустимых для данной команды.
+Токеном может быть _ключевое слово_, _идентификатор_, _литерал_ и другие.
+Токены разделяются пробельными символами (пробел, табуляция, перевод строки) либо _комментариями_. Комментарий не является частью команды и синтаксически эквивалентен пробельному символу.
+
+## Режимы совместимости синтаксиса {#lexer-modes}
+
+Поддерживаются два режима совместимости синтаксиса:
+* Расширенный C++ (по-умолчанию)
+* ANSI SQL
+
+Режим ANSI SQL включается с помощью специального комментария `--!ansi-lexer`, который должен стоять в начале {% if feature_mapreduce %}программы{% else %}запроса{% endif %}.
+
+Особенности интерпретации лексических элементов в разных режимах совместимости описаны ниже.
+
+## Комментарии {#comments}
+
+Поддерживаются следующие виды комментариев:
+
+* Однострочные: начинается с последовательности символов `--` (два минуса _подряд_) и продолжается до конца строки
+* Многострочные: начинается с последовательности символов `/*` и заканчивается на последовательности символов `*/`
+
+``` sql
+SELECT 1; -- A single-line comment
+/*
+ Some multi-line comment
+*/
+```
+В режиме совместимости синтаксиса C++ (по-умолчанию) многострочный комментарий заканчивается на _ближайшей_ последовательности символов `*/`.
+В режиме совместимости синтаксиса ANSI SQL учитывается вложенность многострочных комментариев:
+
+``` sql
+--!ansi_lexer
+SELECT * FROM T; /* комментарий /* вложенный комментарий, без ansi_lexer будет ошибка */ */
+```
+
+## Ключевые слова и идентификаторы {#keywords-and-ids}
+
+**Ключевые слова** – это токены, имеющее фиксированное значение в языке YQL. Примеры ключевых слов – `SELECT`, `INSERT`, `FROM`, `ACTION` и т.д. Ключевые слова регистронезависимы, то есть `SELECT` и `SeLEcT` эквивалентны.
+Список ключевых слов не фиксирован – по мере развития языка он будет расширяться. Ключевое слово не может содержать цифры и начинаться или заканчиваться символом подчеркивания.
+
+**Идентификаторы** – это токены, которые идентифицируют имена таблиц, колонок и других объектов в YQL. Идентификаторы в YQL всегда регистрозависимы.
+Идентификатор может быть записан в теле программы без специального оформления, если он:
+* Не является ключевым словом
+* Начинается с латинской буквы или подчеркивания
+* Последующими символами могут быть латинская буква, подчеркивание или цифра
+
+``` sql
+SELECT my_column FROM my_table; -- my_column and my_table are identifiers
+```
+
+Для записи в теле {% if feature_mapreduce %}программы{% else %}запроса{% endif %} произвольного идентификатора он заключается в обратные кавычки (бэктики):
+``` sql
+SELECT `column with space` from T;
+SELECT * FROM `my_dir/my_table`
+```
+
+Идентификатор в обратных кавычках никогда не интерпретируется как ключевое слово:
+
+``` sql
+SELECT `select` FROM T; -- select - имя колонки в таблице T
+```
+При использовании обратных кавычек применим стандартный C-эскейпинг:
+
+``` sql
+SELECT 1 as `column with\n newline, \x0a newline and \` backtick `;
+```
+
+В режиме совместимости синтаксиса ANSI SQL произвольные идентификаторы также могут быть выделены заключением их в двойные кавычки. Для включения двойной кавычки в идентификатор в кавычках она должна быть удвоена:
+
+``` sql
+--!ansi_lexer
+SELECT 1 as "column with "" double quoute"; -- имя колонки будет: column with " double quoute
+```
+
+## Строковые литералы {#string-literals}
+
+Строковой литерал (константа) записывается как последовательность символов, заключенных в одинарные кавычки. Внутри строкового литерала можно использовать правила эскейпинга в стиле C:
+``` yql
+SELECT 'string with\n newline, \x0a newline and \' backtick ';
+```
+
+В режиме совместимости синтаксиса С++ (по-умолчанию) разрешается использовать вместо одинарных кавычек двойные:
+```yql
+SELECT "string with\n newline, \x0a newline and \" backtick ";
+```
+
+В режиме совместимости синтаксиса ASNI SQL двойные кавычки используются для идентификаторов, а единственный вид эскепинга который действует для строковых литералов – это дублирование символа одиночной кавычки:
+
+```sql
+--!ansi_lexer
+SELECT 'string with '' quote'; -- результат: string with ' quote
+```
+
+### Многострочные строковые литералы {#multiline-string-literals}
+
+Многострочный строковой литерал записывается в виде произвольного набора символов между двойными собачками `@@`:
+
+``` yql
+$text = @@some
+multiline
+text@@;
+SELECT LENGTH($text);
+```
+
+Если необходимо вставить в текст двойную собачку, ее необходимо удвоить:
+
+``` yql
+$text = @@some
+multiline with double at: @@@@
+text@@;
+SELECT $text;
+```
+
+### Типизированные строковые литералы {#typed-string-literals}
+
+* Для строкового литерала, включая [многострочный](#multiline-string-literals), по умолчанию используется тип `String`.
+* С помощью следующих суффиксов можно явно управлять типом литерала:
+ * `u` — `Utf8`;
+ * `y` — `Yson`;
+ * `j` — `Json`.
+
+**Пример:**
+``` yql
+SELECT "foo"u, '[1;2]'y, @@{"a":null}@@j;
+```
+
+## Числовые литералы {#literal-numbers}
+
+* Целочисленные литералы по умолчанию имеют тип `Int32`, если попадают в его диапазон, и в противном случае автоматически расширяются до `Int64`.
+* С помощью следующих суффиксов можно явно управлять типом литерала:
+ * `l` — `Int64`;
+ * `s` — `Int16`;
+ * `t` — `Int8`.
+* Добавление суффикса `u` превращает тип в соответствующий беззнаковый:
+ * `ul` — `Uint64`;
+ * `u` — `Uint32`;
+ * `us` — `Uint16`;
+ * `ut` — `Uint8`.
+* Также для целочисленных литералов доступна запись в шестнадцатеричной, восьмеричной и двоичной форме с помощью префиксов `0x`, `0o` и `0b`, соответственно. Их можно произвольным образом комбинировать с описанными выше суффиксами.
+* Литералы с плавающей точкой по умолчанию имеют тип `Double`, но с помощью суффикса `f` его можно сузить до `Float`.
+
+``` sql
+SELECT
+ 123l AS `Int64`,
+ 0b01u AS `Uint32`,
+ 0xfful AS `Uint64`,
+ 0o7ut AS `Uint8`,
+ 456s AS `Int16`,
+ 1.2345f AS `Float`;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/not_yet_supported.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/not_yet_supported.md
new file mode 100644
index 00000000000..86109cc29d0
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/not_yet_supported.md
@@ -0,0 +1,17 @@
+# Ещё не поддерживаемые конструкции из классического SQL
+
+## \[NOT\] \[EXISTS|INTERSECT\|EXCEPT] {#not-exists}
+
+Доступный альтернативный вариант — `EXISTS` синтаксически доступен, но из-за отсутствия поддержки коррелированных подзапросов не очень полезен. Также можно переписать через `JOIN`.
+
+## UNION {#union}
+
+Доступный альтернативный вариант — `SELECT DISTINCT` по явно перечисленным колонкам + `UNION ALL`, при необходимости с использованием подзапросов.
+
+## NATURAL JOIN {#natural-join}
+
+Доступный альтернативный вариант — явно перечислить совпадающие с обеих сторон колонки.
+
+## NOW() / CURRENT_TIME() {#now}
+
+Доступный альтернативный вариант — воспользоваться функциями [CurrentUtcDate, CurrentUtcDatetime и CurrentUtcTimestamp](../../builtins/basic.md#current-utc).
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/debug.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/debug.md
new file mode 100644
index 00000000000..54d2653580c
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/debug.md
@@ -0,0 +1,39 @@
+{% if tech %}
+
+## Отладочные и служебные {#debug}
+
+{% if feature_webui %}
+### `DirectRead`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Служебная настройка для работы preview таблиц в [HTTP API](../../../interfaces/http.md) (для веб-интерфейса и консольного клиента).
+{% endif %}
+
+### `config.flags("ValidateUdf", "Lazy")`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Строка: None / Lazy / Greedy | None |
+
+Валидация результатов UDF на соответствие объявленной сигнатуре. Greedy режим форсирует материализацию «ленивых» контейнеров, а Lazy — нет.
+
+### `{{ backend_name_lower }}.DefaultCluster`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Строка с именем кластера | hahn |
+
+Выбор кластера для выполнения вычислений, не использующих таблицы.
+
+### `config.flags("Diagnostics")`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Получение диагностической информации от YQL в виде дополнительного результата запроса.
+
+{% endif %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/definition.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/definition.md
new file mode 100644
index 00000000000..b42233b3ea5
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/definition.md
@@ -0,0 +1,38 @@
+## Определение
+
+Переопределение настроек.
+
+**Синтаксис**
+
+`PRAGMA x.y = "z";` или `PRAGMA x.y("z", "z2", "z3");`:
+
+* `x` — (опционально) категория настройки.
+* `y` — название настройки.
+* `z` — (опционально для флагов) значение настройки. Допустимо использование следующих суффиксов:
+ * `Kb`, `Mb`, `Gb` — для объема информации.
+ * `sec`, `min`, `h`, `d` — для временных значений.
+
+**Примеры**
+
+``` yql
+PRAGMA AutoCommit;
+```
+
+``` yql
+PRAGMA TablePathPrefix = "home/yql";
+```
+
+``` yql
+PRAGMA Warning("disable", "1101");
+```
+
+За некоторым исключением, значение настроек можно вернуть в состояние по умолчанию с помощью `PRAGMA my_pragma = default;`.
+
+Полный список доступных настроек [см. в таблице ниже](#pragmas).
+
+### Область действия {#pragmascope}
+
+Если не указано иное, прагма влияет на все идущие следом выражения вплоть до конца модуля, в котором она встречается.
+При необходимости и логической возможности допустимо менять значение настройки несколько раз в одном запросе, чтобы оно было разным на разных этапах выполнения.
+Существуют также специальные scoped прагмы, область действия которых определяется по тем же правилам, что и область видимости [именованных выражений](../../expressions.md#named-nodes).
+В отличие от scoped прагм, обычные прагмы могут использоваться только в глобальной области видимости (не внутри лямбда-функций, ACTION{% if feature_subquery %}, SUBQUERY{% endif %} и т.п.). \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/files.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/files.md
new file mode 100644
index 00000000000..80d1891ff51
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/files.md
@@ -0,0 +1,59 @@
+
+{% if feature_mapreduce %}
+
+## Работа с файлами
+
+### File
+
+| Тип значения | По умолчанию | Статическая /<br/>динамическая |
+| --- | --- | --- |
+| Два строковых аргумента — алиас и URL | — | Статическая |
+
+Приложить файл к запросу по URL. Использовать приложенные файлы можно с помощью встроенных функций [FilePath и FileContent](../../../builtins/basic.md#filecontent). Данная `PRAGMA` является универсальной альтернативой прикладыванию файлов с использованием встроенных механизмов [веб-](../../../interfaces/web.md#attach) или [консольного](../../../interfaces/cli.md#attach) клиентов.
+
+Сервис YQL оставляет за собой право кешировать находящиеся за URL файлы на неопределенный срок, по-этому при значимом изменении находящегося за ней содержимого настоятельно рекомендуется модифицировать URL за счет добавления/изменения незначащих параметров.
+
+### Folder
+
+| Тип значения | По умолчанию | Статическая /<br/>динамическая |
+| --- | --- | --- |
+| Два строковых аргумента — префикс и URL | — | Статическая |
+
+Приложить набор файлов к запросу по URL. Работает аналогично добавлению множества файлов через `PRAGMA File`](#file) по прямым ссылкам на файлы с алиасами, полученными объединением префикса с именем файла через `/`.
+
+### Library
+
+| Тип значения | По умолчанию | Статическая /<br/>динамическая |
+| --- | --- | --- |
+| Один или два аргумента - имя файла и опциональный URL | — | Статическая |
+
+Интерпретировать указанный приложенный файл как библиотеку, из которой можно делать [IMPORT](../../export_import.md). Тип синтаксиса библиотеки определяется по расширению файла:
+* `.sql` для YQL диалекта SQL <span style="color: green;">(рекомендуется)</span>;
+* `.yql` для [s-expressions](/docs/s_expressions).
+
+Пример с приложенным файлом к запросу:
+
+``` yql
+PRAGMA library("a.sql");
+IMPORT a SYMBOLS $x;
+SELECT $x;
+```
+
+В случае указания URL библиотека скачивается с него, а не с предварительного приложенного файла, как в следующем примере:
+
+``` yql
+PRAGMA library("a.sql","https://paste.yandex-team.ru/5618566/text");
+IMPORT a SYMBOLS $x;
+SELECT $x;
+```
+
+При этом можно использовать подстановку текстовых параметров в URL:
+
+``` yql
+DECLARE $_ver AS STRING; -- "5618566"
+PRAGMA library("a.sql","https://paste.yandex-team.ru/{$_ver}/text");
+IMPORT a SYMBOLS $x;
+SELECT $x;
+```
+
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/global.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/global.md
new file mode 100644
index 00000000000..63fd940dce7
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/global.md
@@ -0,0 +1,216 @@
+## Глобальные {#pragmas}
+
+### AutoCommit {#autocommit}
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Автоматически выполнять [COMMIT](../../select.md#commit) после каждого выражения.
+
+### TablePathPrefix {#table-path-prefix}
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Строка | — |
+
+Добавить указанный префикс к путям таблиц внутри кластеров. Работает по принципу объединения путей в файловой системе: поддерживает ссылки на родительский каталог `..` и не требует добавления слеша справа. Например,
+
+`PRAGMA TablePathPrefix = "home/yql";
+SELECT * FROM test;`
+
+Префикс не добавляется, если имя таблицы указано как абсолютный путь (начинается с /).
+
+### UseTablePrefixForEach {#use-table-prefix-for-each}
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+EACH использует [TablePathPrefix](#table-path-prefix) для каждого элемента списка.
+
+### Warning {#warning}
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| 1. Действие<br>2. Код предупреждения либо символ "*"| — |
+
+Действие:
+* `disable` — отключить;
+* `error` — приравнять к ошибке;
+* `default` — вернуть поведение по умолчанию.
+
+Код предупреждения возвращается вместе с самим текстом (в веб-интерфейсе отображается справа).
+
+Пример:
+`PRAGMA Warning("error", "*");`
+`PRAGMA Warning("disable", "1101");`
+`PRAGMA Warning("default", "4503");`
+
+В данном случае все предупреждения будут считаться ошибками, за исключением предупреждение с кодом `1101`, которое будет отключено, и `4503`, которое будет обрабатываться по умолчанию (то есть останется предупреждением). Поскольку предупреждения могут добавляться в новых релизах YQL, следует с осторожностью пользоваться конструкцией `PRAGMA Warning("error", "*");` (как минимум покрывать такие запросы автотестами).
+
+{% include [issue_protos.md](issue_protos.md) %}
+
+{% if feature_mapreduce %}
+### DqEngine {#dqengine}
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Строка disable/auto/force | "auto" |
+
+При значении "auto" включает новый движок вычислений. Вычисления по возможности делаются без создания map/reduce операций. При значении "force" вычисление идет в новый движок безусловно.
+{% endif %}
+
+{% if feature_join %}
+### SimpleColumns {#simplecolumns}
+
+`SimpleColumns` / `DisableSimpleColumns`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | true |
+
+При использовании `SELECT foo.* FROM ... AS foo` убрать префикс `foo.` у имен результирующих колонок.
+
+Работает в том числе и для [JOIN](../../join.md), но в этом случае имеет право упасть в случае конфликта имен (который можно разрешить с помощью [WITHOUT](../../select.md#without) и переименования колонок). Для JOIN в режиме SimpleColumns производится неявный Coalesce для ключевых колонок: запрос `SELECT * FROM T1 AS a JOIN T2 AS b USING(key)` в режиме SimpleColumns работает как `SELECT a.key ?? b.key AS key, ... FROM T1 AS a JOIN T2 AS b USING(key)`
+
+### CoalesceJoinKeysOnQualifiedAll
+
+`CoalesceJoinKeysOnQualifiedAll` / `DisableCoalesceJoinKeysOnQualifiedAll`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | true |
+
+Управляет неявным Coalesce для ключевых колонок `JOIN` в режиме SimpleColumns. Если флаг установлен, то Coalesce ключевых колонок происходит при наличии хотя бы одного выражения вида `foo.*` или `*` в SELECT - например `SELECT a.* FROM T1 AS a JOIN T2 AS b USING(key)`. Если флаг сброшен, то Coalesce ключей JOIN происходит только при наличии '*' после `SELECT`
+
+### StrictJoinKeyTypes
+`StrictJoinKeyTypes` / `DisableStrictJoinKeyTypes`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Если флаг установлен, то [JOIN](../../join.md) будет требовать строгого совпадения типов ключей.
+По умолчанию JOIN предварительно конвертирует ключи к общему типу, что может быть нежелательно с точки зрения производительности.
+StrictJoinKeyTypes является [scoped](#pragmascope) настройкой.
+
+{% endif %}
+
+### AnsiInForEmptyOrNullableItemsCollections
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Наличие этой прагмы приводит поведение оператора `IN` в соответствие со стандартом в случае наличия `NULL` в левой или правой части оператора `IN`. Также изменено поведение `IN` в случае, когда справа был Tuple с элементами разных типов. Примеры:
+
+`1 IN (2, 3, NULL) = NULL (было Just(False))`
+`NULL IN () = Just(False) (было NULL)`
+`(1, null) IN ((2, 2), (3, 3)) = Just(False) (было NULL)`
+`2147483648u IN (1, 2147483648u) = True (было False)`
+
+Подробнее про поведение `IN` при наличии `NULL`ов в операндах можно почитать [здесь](../../expressions.md#in). Явным образом выбрать старое поведение можно указав прагму `DisableAnsiInForEmptyOrNullableItemsCollections`. Если никакой прагмы не задано, то выдается предупреждение и работает старый вариант.
+
+### AnsiRankForNullableKeys
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Приводит поведение RANK/DENSE_RANK в соответствие со стандартом при наличии опциональных типов в ключах сортировки окна или в аргументе этих оконных функций. А именно:
+* типом результата всегда является Uint64, а не Uint64?;
+* null-ы в ключах считаются равными друг другу (текущая реализация возвращает NULL).
+Явным образом выбрать старое поведению можно указав прагму `DisableAnsiRankForNullableKeys`. Если никакой прагмы не задано, то выдается предупреждение и работает старый вариант.
+
+### AnsiCurrentRow
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Приводит неявное задание рамки окна при наличии ORDER BY в соответствие со стандартом.
+Если AnsiCurrentRow не установлен, то окно `(ORDER BY key)` эквивлентно `(ORDER BY key ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)`.
+Стандарт же требует, чтобы такое окно вело себя как `(ORDER BY key RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)`.
+Разница состоит в трактовке `CURRENT ROW`. В режиме `ROWS` `CURRENT ROW` трактуется буквально – текущая строка в партиции.
+А в режиме `RANGE` конец рамки `CURRENT ROW` означает "последния строка в партиции с ключем сортировки равным текущей строке".
+
+### AnsiOrderByLimitInUnionAll
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Приводит поведение UNION ALL в соответствие со стандартом при наличии `ORDER BY/LIMIT/DISCARD/INSERT INTO` в объединяемых подзапросах. А именно:
+* `ORDER BY/LIMIT/INSERT INTO` допускается только после последнего подзапроса;
+* `DISCARD` допускается только перед первым подзапросом;
+* указанные операторы действуют на результат `UNION ALL` (в отличии от текущего поведения, когда они действуют на подзапрос);
+* чтобы применить оператор к подзапросу, подзапрос необходимо взять в скобки.
+
+Явным образом выбрать старое поведению можно указав прагму `DisableAnsiOrderByLimitInUnionAll`. Если никакой прагмы не задано, то выдается предупреждение и работает старый вариант.
+
+### OrderedColumns {#orderedcolumns}
+`OrderedColumns` / `DisableOrderedColumns`
+
+Выводить [порядок колонок](../../select.md#orderedcolumns) в SELECT/JOIN/UNION ALL и сохранять его при записи результатов. По умолчанию порядок колонок не определен.
+
+### PositionalUnionAll {#positionalunionall}
+
+Включить соответствующий стандарту поколоночный режим выполнения [UNION ALL](../../select.md#unionall). При этом автоматически включается
+[упорядоченность колонок](#orderedcolumns).
+
+### RegexUseRe2
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Использовать Re2 UDF вместо Pcre для выполнения SQL операторов `REGEX`,`MATCH`,`RLIKE`. Re2 UDF поддерживает корректную обработку Unicode-символов в отличие от используемой по умолчанию Pcre UDF.
+
+### ClassicDivision
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | true |
+
+В классическом варианте результат целочисленного деления остаётся целочисленным (по умолчанию).
+Если отключить — результат всегда становится Double.
+ClassicDivision является [scoped](#pragmascope) настройкой.
+
+### AllowDotInAlias
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Разрешить использовать точку в именах результирующих колонок. По умолчанию отключено, т.к. дальнейшее использование таких колонок в JOIN полностью не реализовано.
+
+### WarnUnnamedColumns
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Генерировать предупреждение если для безымянного выражения в `SELECT` было автоматически сгенерировано имя колонки (вида `column[0-9]+`).
+
+### GroupByLimit
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Положительное число | 32 |
+
+Увеличение лимита на число группировок в [GROUP BY](../../group_by.md).
+
+{% if feature_group_by_rollup_cube %}
+
+### GroupByCubeLimit
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Положительное число | 5 |
+
+Увеличение лимита на число размерностей [GROUP BY](../../group_by.md#rollup-cube-group-sets).
+
+Использовать нужно аккуратно, так как вычислительная сложность запроса растет экспоненциально по отношению к числу размерностей.
+
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/issue_protos.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/issue_protos.md
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/issue_protos.md
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/ydb.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/ydb.md
new file mode 100644
index 00000000000..c8385612ae1
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/ydb.md
@@ -0,0 +1,13 @@
+{% if tech %}
+
+## YDB
+
+### `kikimr.IsolationLevel`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Serializable, ReadCommitted, ReadUncommitted или ReadStale. | Serializable |
+
+Экспериментальная pragma, позволяет ослабить уровень изоляции текущей транзакции в YDB.
+
+{% endif %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/yson.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/yson.md
new file mode 100644
index 00000000000..02871997d27
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/pragma/yson.md
@@ -0,0 +1,27 @@
+## Yson
+
+Управление поведением Yson UDF по умолчанию, подробнее см. в [документации по ней](../../../udf/list/yson.md) и в частности [Yson::Options](../../../udf/list/yson.md#ysonoptions).
+
+### `yson.AutoConvert`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Автоматическое конвертация значений в требуемый тип данных во всех вызовах Yson UDF, в том числе и неявных.
+
+### `yson.Strict`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | true |
+
+Управление строгим режимом во всех вызовах Yson UDF, в том числе и неявных. Без значения или при значении `"true"` - включает строгий режим. Со значением `"false"` - отключает.
+
+### `yson.DisableStrict`
+
+| Тип значения | По умолчанию |
+| --- | --- |
+| Флаг | false |
+
+Инвертированная версия `yson.Strict`. Без значения или при значении `"true"` - отключает строгий режим. Со значением `"false"` - включает.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/process.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/process.md
new file mode 100644
index 00000000000..bcac336583b
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/process.md
@@ -0,0 +1,125 @@
+# {{ process_command }}
+
+Преобразовать входную таблицу с помощью UDF на [C++](../../udf/cpp.md){% if yt %}, [Python](../../udf/python.md) или [JavaScript](../../udf/javascript.md){% endif %} или [лямбда функции](../../syntax/expressions.md#lambda), которая применяется последовательно к каждой строке входа и имеет возможность для каждой строки входа создать ноль, одну или несколько строк результата (аналог Map в терминах MapReduce).
+
+{% if feature_mapreduce %}Таблица по имени ищется в базе данных, заданной оператором [USE](../use.md).{% endif %}
+
+В параметрах вызова функции после ключевого слова `USING` явно указывается, значения из каких колонок и в каком порядке передавать для каждой строки входа.
+
+Допустимы функции, которые возвращают результат одного из трех составных типов от `OutputType` (возможные варианты `OutputType` описаны ниже):
+
+* `OutputType` — на каждую строку входа всегда должна быть строка выхода, схема которой определяется типом структуры.
+* `OutputType?` — функции оставляет за собой право пропускать строки, возвращая пустые значения (`TUnboxedValue()` в C++, `None` в Python или `null` в JavaScript).
+* `Stream<OutputType>` или `List<OutputType>` — возможность вернуть несколько строк.
+
+Вне зависимости от того, какой вариант из перечисленных выше трех выбран, результат преобразовывается к плоской таблице с колонками, определяемыми типом `OutputType`.
+
+В качестве `OutputType` может выступать один из типов:
+
+* `Struct<...>` — у `{{ process_command }}` будет ровно один выход с записями заданной структуры, представляющий собой плоскую таблицу с колонками соответствующими полям `Struct<...>`
+* `Variant<Struct<...>,...>` — у `{{ process_command }}` число выходов будет равно числу альтернатив в `Variant`. Записи каждого выхода представлены плоской таблицей с колонками по полям из соответствующей альтернативы. Ко множеству выходов `{{ process_command }}` в этом случае можно обратиться как к кортежу (`Tuple`) списков, который можно распаковать в отдельные [именованные выражения](../expressions.md#named-nodes) и использовать независимо.
+
+В списке аргументов функции после ключевого слова `USING` можно передать одно из двух специальных именованных выражений:
+
+* `TableRow()` — текущая строка целиком в виде структуры;
+* `TableRows()` — ленивый итератор по строкам, с точки зрения типов — `Stream<Struct<...>>`. В этом случае выходным типом функции может быть только `Stream<OutputType>` или `List<OutputType>`.
+
+{% note info "Примечание" %}
+
+После выполнения `{{ process_command }}` в рамках того же запроса по результирующей таблице (или таблицам) можно выполнить {% if select_command != "SELECT STREAM" %}[SELECT](../select.md), [REDUCE](../reduce.md){% else %}[SELECT STREAM](../select_stream.md){% endif %}, [INSERT INTO](../insert_into.md), ещё один `{{ process_command }}` и так далее в зависимости от необходимого результата.
+
+{% endnote %}
+
+Ключевое слово `USING` и указание функции необязательны: если они не указаны, то возвращается исходная таблица. {% if feature_subquery %}Это может быть удобно для применения [шаблона подзапроса](subquery.md).{% endif %}
+
+В `{{ process_command }}` можно передать несколько входов (под входом здесь подразумевается таблица,{% if select_command != "PROCESS STREAM" %} [диапазон таблиц](../select.md#range){% endif %}, подзапрос, [именованное выражение](../expressions.md#named-nodes)), разделенных запятой. В функцию из `USING` в этом случае можно передать только специальные именованные выражения `TableRow()` или `TableRows()`, которые будут иметь следующий тип:
+
+* `TableRow()` — альтернатива (`Variant`), где каждый элемент имеет тип структуры записи из соответствущего входа. Для каждой входной строки в альтернативе заполнен элемент, соответствущий номеру входа этой строки
+* `TableRows()` — ленивый итератор по альтернативам, с точки зрения типов — `Stream<Variant<...>>`. Альтернатива имеет такую же семантику, что и для `TableRow()`
+
+После `USING` в `{{ process_command }}` можно опционально указать `ASSUME ORDER BY` со списком столбцов. Результат такого `{{ process_command }}` будет считаться сортированным, но без выполнения фактической сортировки. Проверка сортированности осуществляется на этапе исполнения запроса. Поддерживается задание порядка сортировки с помощью ключевых слов `ASC` (по возрастанию) и `DESC` (по убыванию). Выражения в `ASSUME ORDER BY` не поддерживается.
+
+**Примеры:**
+
+{% if process_command != "PROCESS STREAM" %}
+``` yql
+PROCESS my_table
+USING MyUdf::MyProcessor(value)
+```
+
+``` yql
+$udfScript = @@
+def MyFunc(my_list):
+ return [(int(x.key) % 2, x) for x in my_list]
+@@;
+
+-- Функция возвращает итератор альтернатив
+$udf = Python3::MyFunc(Callable<(Stream<Struct<...>>) -> Stream<Variant<Struct<...>, Struct<...>>>>,
+ $udfScript
+);
+
+-- На выходе из PROCESS получаем кортеж списков
+$i, $j = (PROCESS my_table USING $udf(TableRows()));
+
+SELECT * FROM $i;
+SELECT * FROM $j;
+```
+
+``` yql
+$udfScript = @@
+def MyFunc(stream):
+ for r in stream:
+ yield {"alt": r[0], "key": r[1].key}
+@@;
+
+-- Функция принимает на вход итератор альтернатив
+$udf = Python::MyFunc(Callable<(Stream<Variant<Struct<...>, Struct<...>>>) -> Stream<Struct<...>>>,
+ $udfScript
+);
+
+PROCESS my_table1, my_table2 USING $udf(TableRows());
+```
+
+{% else %}
+```yql
+
+-- лямбда функция принимает примитивный тип и возвращает структуру с тремя одинаковыми полями
+$f = ($r) -> {
+ return AsStruct($r as key, $r as subkey, $r as value);
+};
+
+-- фильтруем входящий стрим в секции WHERE
+PROCESS STREAM Input USING $f(value) WHERE cast(subkey as int) > 3;
+
+```
+
+``` yql
+-- лямбда функция принимает тип `Struct<key:String, subkey:String, value:String>`
+-- и возвращает аналогичную структуру, добавив некий суффикс к каждому полю
+
+$f = ($r) -> {
+ return AsStruct($r.key || "_1" as key, $r.subkey || "_2" as subkey, $r.value || "_3" as value);
+};
+
+PROCESS STREAM Input USING $f(TableRow());
+```
+
+``` yql
+-- лямбда функция принимает запись типа `Struct<...>`
+-- и возвращает список из двух одинаковых элементов
+$f1 = ($x) -> {
+ return AsList($x, $x);
+};
+
+-- лямбда функция принимает и возвращает тип `Stream<Struct<...>>`
+-- применяет к каждому элементу функцию $f1 и возвращает строчки-дубликаты
+$f2 = ($x) -> {
+ return ListFlatMap($x, $f1);
+};
+
+$p = (PROCESS STREAM Input USING $f2(TableRows()));
+
+SELECT STREAM * FROM $p;
+
+```
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/reduce.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/reduce.md
new file mode 100644
index 00000000000..bca2299e694
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/reduce.md
@@ -0,0 +1,103 @@
+# REDUCE
+
+Выполняет группировку входа по указанным ключевым столбцам, затем передает текущие ключи и ленивый итератор соответствующих им значений из остальных колонок на обработку в указанную UDF. По аналогии с `PROCESS` UDF может вернуть произвольное количество строк результата на каждый вызов, а также возвращать альтернативы (`Variant`) для создания множества выходов. В терминах MapReduce очень близок к Reduce.
+
+Указываемые следом ключевые слова:
+
+* `PRESORT` <span style="color: gray;">(опционально)</span> — указание порядка внутри каждой группы, синтаксис аналогичен [ORDER BY](../select.md#orderby);
+* `ON` <span style="color: gray;">(обязательно)</span> — указание ключевых столбцов;
+* `USING` или `USING ALL` <span style="color: gray;">(обязательно)</span> — вызов UDF, о правилах подробнее ниже.
+
+Правила передачи аргументов UDF:
+
+* Если аргументом UDF указан `TableRows()`, то UDF обязана принимать один аргумент — ленивый итератор по строкам, с точки зрения типов — `Stream<Struct<...>>`. В этом случае выходным типом функции может быть только `Stream<OutputType>` или `List<OutputType>`. Гарантируется, что данные во входном итераторе сгруппированы по ключу и, при необходимости, отсортированы согласно `PRESORT` секции. С `TableRows()` можно использовать только `USING ALL`.
+* При использовании `USING`:
+ * UDF обязана принимать два аргумента: в первый передается текущий ключ, а во второй — ленивый итератор с соответствующими этому ключу значениями.
+* При использовании `USING ALL`:
+ * UDF обязана принимать один аргумент — ленивый итератор кортежей (`Tuple`), где первый элемент кортежа это ключ, а второй — ленивый итератор с соответствующими этому ключу значениями.
+* Ключ для передачи в UDF формируется по следующему правилу. Если ключевая колонка одна, то её значение формирует ключ как есть, если несколько (список колонок указывается по аналогии с `GROUP BY` через запятую), то ключ будет формироваться как кортеж (`Tuple`) со значениями из перечисленных колонок в указанном порядке.
+* При вызове `REDUCE` в запросе в круглых скобках после имени UDF указываются только выражение, значения которого будут переданы в качестве элементов итератора (второй аргумент UDF для `USING` или второй элемент кортежа для `USING ALL`).
+
+Результат формируется аналогичным [PROCESS](../process.md) образом. Также доступно ключевое слово `TableRow()` для получения строки целиком в виде структуры.
+
+В `REDUCE` можно передать несколько входов (под входом здесь подразумевается таблица, [диапазон таблиц](../select.md#range), подзапрос, [именованное выражение](../expressions.md#named-nodes)), разделенных запятой. Все входы обязаны иметь указанные в `ON` ключевые колонки совпадающего типа. В функцию из `USING` в этом случае можно передать только специальное именованное выражение `TableRow()`. Второй аргумент (или второй элемент кортежа для `USING ALL`) будет содержать ленивый итератор альтернатив с заполненным элементом, соответствущим номеру входа текущей записи.
+
+После `USING` в `REDUCE` можно опционально указать `ASSUME ORDER BY` со списком столбцов. Результат такого `REDUCE` будет считаться сортированным, но без выполнения фактической сортировки. Проверка сортированности осуществляется на этапе исполнения запроса. Поддерживается задание порядка сортировки с помощью ключевых слов `ASC` (по возрастанию) и `DESC` (по убыванию). Выражения в `ASSUME ORDER BY` не поддерживается.
+
+**Примеры:**
+``` yql
+REDUCE my_table
+ON key, subkey
+USING MyUdf::MyReducer(TableRow());
+```
+
+``` yql
+REDUCE my_table
+ON key, subkey
+USING ALL MyUdf::MyStreamReducer(TableRow()); -- MyUdf::MyStreamReducer принимает на вход ленивый список кортежей (ключ, список записей для ключа)
+```
+
+``` yql
+REDUCE my_table
+PRESORT LENGTH(subkey) DESC
+ON key
+USING MyUdf::MyReducer(
+ AsTuple(subkey, value)
+);
+```
+
+``` yql
+REDUCE my_table
+ON key
+USING ALL MyUdf::MyFlatStreamReducer(TableRows()); -- MyUdf::MyFlatStreamReducer принимает на вход единый ленивый список записей
+```
+
+``` yql
+-- Функция возвращает альтернативы
+$udf = Python::MyReducer(Callable<(String, Stream<Struct<...>>) -> Variant<Struct<...>, Struct<...>>>,
+ $udfScript
+);
+
+-- На выходе из REDUCE получаем кортеж списков
+$i, $j = (REDUCE my_table ON key USING $udf(TableRow()));
+
+SELECT * FROM $i;
+SELECT * FROM $j;
+```
+
+
+``` yql
+$script = @@
+def MyReducer(key, values):
+ state = None, 0
+ for name, last_visit_time in values:
+ if state[1] < last_visit_time:
+ state = name, last_visit_time
+ return {
+ 'region':key,
+ 'last_visitor':state[0],
+ }
+@@;
+
+$udf = Python::MyReducer(Callable<(
+ Int64?,
+ Stream<Tuple<String?, Uint64?>>
+) -> Struct<
+ region:Int64?,
+ last_visitor:String?
+>>,
+ $script
+);
+
+REDUCE hahn.`home/yql/tutorial/users`
+ON region USING $udf((name, last_visit_time));
+```
+
+``` yql
+-- Функция принимает на вход ключ и итератор альтернатив
+$udf = Python::MyReducer(Callable<(String, Stream<Variant<Struct<...>,Struct<...>>>) -> Struct<...>>,
+ $udfScript
+);
+
+REDUCE my_table1, my_table2 ON key USING $udf(TableRow());
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/replace_into.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/replace_into.md
new file mode 100644
index 00000000000..9d0604ecb47
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/replace_into.md
@@ -0,0 +1,31 @@
+# REPLACE INTO
+
+Сохраняет данные в таблицу с перезаписью строк по первичному ключу.{% if feature_mapreduce %} Таблица по имени ищется в базе данных, заданной оператором [USE](../use.md).{% endif %} Если заданный первичный ключ отсутствует, в таблицу будет добавлена новая строка. Если задан существующий `PRIMARY_KEY`, строка будет перезаписана. При этом значения столбцов, не участвующих в операции, заменяются на значения по умолчанию.
+
+{% note info %}
+
+В отличие от [`INSERT INTO`](../insert_into.md) и [`UPDATE`](../update.md), запросы [`UPSERT INTO`](../upsert_into.md) и `REPLACE INTO` не требуют предварительного чтения данных, поэтому выполняются быстрее.
+
+{% endnote %}
+
+* Задание значений для `REPLACE INTO` c помощью `VALUES`.
+
+ **Пример**
+
+ ```sql
+ REPLACE INTO my_table (Key1, Key2, Value2) VALUES
+ (1u, "One", 101),
+ (2u, "Two", 102);
+ COMMIT;
+ ```
+
+* Получение значений для `REPLACE INTO` с помощью выборки `SELECT`.
+
+ **Пример**
+
+ ```sql
+ REPLACE INTO my_table
+ SELECT Key AS Key1, "Empty" AS Key2, Value AS Value1
+ FROM my_table1;
+ COMMIT;
+ ```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/assume_order_by.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/assume_order_by.md
new file mode 100644
index 00000000000..829435caecb
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/assume_order_by.md
@@ -0,0 +1,14 @@
+
+## ASSUME ORDER BY
+
+Проверка сортированности результата `SELECT` по значению в указанном столбце или нескольких столбцах. Результат такого `SELECT`-а будет считаться сортированным, но без выполнения фактической сортировки. Проверка сортированности осуществляется на этапе исполнения запроса.
+
+Как и для `ORDER BY`, поддерживается задание порядка сортировки с помощью ключевых слов `ASC` (по возрастанию) и `DESC` (по убыванию). Выражения в `ASSUME ORDER BY` не поддерживается.
+
+**Примеры:**
+
+``` yql
+SELECT key || "suffix" as key, -CAST(subkey as Int32) as subkey
+FROM my_table
+ASSUME ORDER BY key, subkey DESC;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/calc.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/calc.md
new file mode 100644
index 00000000000..42a7c3a0882
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/calc.md
@@ -0,0 +1,15 @@
+## SELECT
+
+Возвращает результат вычисления выражений, указанных после `SELECT`.
+
+Может использоваться в сочетании с другими операциями для получения иного эффекта.
+
+**Примеры:**
+
+``` yql
+SELECT "Hello, world!";
+```
+
+``` yql
+SELECT 2 + 2;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/column_order.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/column_order.md
new file mode 100644
index 00000000000..1837d311fe8
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/column_order.md
@@ -0,0 +1,21 @@
+## Порядок колонок в YQL {#orderedcolumns}
+В стандартном SQL порядок колонок указанных в проекции (в `SELECT`) имеет значение. Помимо того, что порядок колонок должен сохраняться при отображении результатов запроса или при записи в новую таблицу, некоторые конструкции SQL этот порядок используют.
+Это относится в том числе к [UNION ALL](#unionall) и к позиционному [ORDER BY](#orderby) (ORDER BY ordinal).
+
+По умолчанию в YQL порядок колонок игнорируется:
+* порядок колонок в выходных таблицах и в результатах запроса не определен
+* схема данных результата `UNION ALL` выводится по именам колонок, а не по позициям
+
+При включении `PRAGMA OrderedColumns;` порядок колонок сохраняется в результатах запроса и выводится из порядка колонок во входных таблицах по следующим правилам:
+* `SELECT` с явным перечислением колонок задает соответствующий порядок;
+* `SELECT` со звездочкой (`SELECT * FROM ...`) наследует порядок из своего входа;
+{% if feature_join %}* порядок колонок после [JOIN](../../join.md): сначала колонки левой стороны, потом правой. Если порядок какой-либо из сторон присутствующей в выходе `JOIN` не определен, порядок колонок результата также не определен;{% endif %}
+* порядок `UNION ALL` зависит от режима выполнения [UNION ALL](#unionall);
+* порядок колонок для [AS_TABLE](#as_table) не определен;
+
+{% note warning "Внимание" %}
+
+В схеме таблиц YT ключевые колонки всегда идут перед неключевыми колонками. Порядок ключевых колонок определяется порядком составного ключа.
+При включенной `PRAGMA OrderedColumns;` неключевые колонки будут сохранять выведенный порядок.
+
+{% endnote %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/commit.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/commit.md
new file mode 100644
index 00000000000..0fd621df0cd
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/commit.md
@@ -0,0 +1,16 @@
+## COMMIT {#commit}
+
+По умолчанию весь YQL запрос выполняется в рамках одной транзакции и независимые его части внутри выполняются по возможности параллельно.
+С помощью ключевого слова `COMMIT;` можно добавить барьер в процесс выполнения, чтобы отложить выполнение идущих следом выражений до тех пор, пока не выполнятся все предшествующие.
+
+Чтобы коммит выполнялся аналогичным образом автоматически после каждого выражения в запросе, можно использовать `PRAGMA autocommit;`.
+
+**Примеры:**
+
+``` yql
+INSERT INTO result1 SELECT * FROM my_table;
+INSERT INTO result2 SELECT * FROM my_table;
+COMMIT;
+-- В result2 уже будет содержимое SELECT со второй строки:
+INSERT INTO result3 SELECT * FROM result2;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/distinct.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/distinct.md
new file mode 100644
index 00000000000..e36eec857ee
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/distinct.md
@@ -0,0 +1,20 @@
+
+
+## DISTINCT {#distinct}
+
+Выбор уникальных строк.
+
+{% note info %}
+
+Применение `DISTINCT` к вычислимым значениям на данный момент не реализовано. С этой целью можно использовать подзапрос или выражение [`GROUP BY ... AS ...`](../../group_by.md).
+
+{% endnote %}
+
+**Пример**
+
+``` yql
+SELECT DISTINCT value -- только уникальные значения из таблицы
+FROM my_table;
+```
+
+Также ключевое слово `DISTINCT` может использоваться для применения [агрегатных функций](../../../builtins/aggregation.md) только к уникальным значениям. Подробнее см. в документации по [GROUP BY](../../group_by.md). \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/execution.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/execution.md
new file mode 100644
index 00000000000..f31e765468c
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/execution.md
@@ -0,0 +1,19 @@
+## Процедура выполнения SELECT {#selectexec}
+
+Результат запроса `SELECT` вычисляется следующим образом:
+
+* определяется набор входных таблиц – вычисляются выражения после [FROM](#from);
+* к входным таблицам применяется [SAMPLE](#sample) / [TABLESAMPLE](#sample)
+* выполняется [FLATTEN COLUMNS](../../flatten.md#flatten-columns) или [FLATTEN BY](../../flatten.md); алиасы, заданные во `FLATTEN BY`, становятся видны после этой точки;
+{% if feature_join %}* выполняются все [JOIN](../../join.md);{% endif %}
+* к полученным данным добавляются (или заменяются) колонки, заданные в [GROUP BY ... AS ...](../../group_by.md);
+* выполняется [WHERE](#where) &mdash; все данные не удовлетворяющие предикату отфильтровываются;
+* выполняется [GROUP BY](../../group_by.md), вычисляются значения агрегатных функций;
+* выполняется фильтрация [HAVING](../../group_by.md#having);
+{% if feature_window_functions %} * вычисляются значения [оконных функций](../../window.md);{% endif %}
+* вычисляются выражения в `SELECT`;
+* выражениям в `SELECT` назначаются имена заданные алиасами;
+* к полученным таким образом колонкам применяется top-level [DISTINCT](#distinct);
+* таким же образом вычисляются все подзапросы в [UNION ALL](#unionall), выполняется их объединение (см. [PRAGMA AnsiOrderByLimitInUnionAll](../../pragma.md#pragmas));
+* выполняется сортировка согласно [ORDER BY](#order-by);
+* к полученному результату применяются [OFFSET и LIMIT](#limit-offset).
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/folder.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/folder.md
new file mode 100644
index 00000000000..61b65c05306
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/folder.md
@@ -0,0 +1,44 @@
+
+## Перечисление содержимого директории на кластере {#folder}
+
+Указывается как функция `FOLDER` в [FROM](#from).
+
+Аргументы:
+
+1. Путь к директории;
+2. Опционально строка со списком интересующих мета атрибутов через точку с запятой.
+
+В результате получается таблица с тремя фиксированными колонками:
+
+1. **Path** (`String`) — полное имя таблицы;
+2. **Type** (`String`) — тип узла (table, map_node, file, document и пр.);
+3. **Attributes** (`Yson`) — Yson-словарь с заказанными во втором аргументе мета атрибутами.
+
+Рекомендации по использованию:
+
+* Чтобы получить только список таблиц, нужно не забывать добавлять `...WHERE Type == "table"`. Затем, опционально добавив ещё условий, с помощью агрегатной функции [AGGREGATE_LIST](../../../builtins/aggregation.md#aggregate-list) от колонки Path можно получить только список путей и передать их в [EACH](#each).
+* Так как колонка Path выдаётся в том же формате, что и результат функции [TablePath()](../../../builtins/basic.md#tablepath), то их можно использоваться для JOIN атрибутов таблицы к её строкам.
+* C колонкой Attributes рекомендуется работать через [Yson UDF](../../../udf/list/yson.md).
+
+{% note warning "Внимание" %}
+
+Следует с осторожностью использовать FOLDER с атрибутами, содержащими большие значения (`schema` может быть одним из таких). Запрос с FOLDER на папке с большим число таблиц и тяжелым атрибутом может создать большую нагрузку на мастер YT.
+
+{% endnote %}
+
+**Примеры:**
+
+``` yql
+USE hahn;
+
+$table_paths = (
+ SELECT AGGREGATE_LIST(Path)
+ FROM FOLDER("my_folder", "schema;row_count")
+ WHERE
+ Type = "table" AND
+ Yson::GetLength(Attributes.schema) > 0 AND
+ Yson::LookupInt64(Attributes, "row_count") > 0
+);
+
+SELECT COUNT(*) FROM EACH($table_paths);
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from.md
new file mode 100644
index 00000000000..227c201c171
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from.md
@@ -0,0 +1,21 @@
+## FROM {#from}
+
+Источник данных для `SELECT`. В качестве аргумента может принимать имя таблицы, результат другого `SELECT` или [именованное выражение](../../expressions.md#named-nodes). Между `SELECT` и `FROM` через запятую указываются имена столбцов из источника или `*` для выбора всех столбцов.
+
+{% if feature_mapreduce %}Таблица по имени ищется в базе данных, заданной оператором [USE](../../use.md).{% endif %}
+
+**Примеры**
+
+``` yql
+SELECT key FROM my_table;
+```
+
+``` yql
+SELECT * FROM
+ (SELECT value FROM my_table);
+```
+
+``` yql
+$table_name = "my_table";
+SELECT * FROM $table_name;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from_as_table.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from_as_table.md
new file mode 100644
index 00000000000..4664427c3b0
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from_as_table.md
@@ -0,0 +1,16 @@
+## FROM AS_TABLE {#as-table}
+
+Обращение к именованным выражениям как к таблицам с помощью функции `AS_TABLE`.
+
+`AS_TABLE($variable)` позволяет использовать значение `$variable` в качестве источника данных для запроса. При этом переменная `$variable` должна иметь тип `List<Struct<...>>`.
+
+**Пример**
+
+``` yql
+$data = AsList(
+ AsStruct(1u AS Key, "v1" AS Value),
+ AsStruct(2u AS Key, "v2" AS Value),
+ AsStruct(3u AS Key, "v3" AS Value));
+
+SELECT Key, Value FROM AS_TABLE($data);
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from_select.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from_select.md
new file mode 100644
index 00000000000..7dda0a3f4c2
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/from_select.md
@@ -0,0 +1,17 @@
+
+## FROM ... SELECT ... {#from-select}
+
+Перевернутая форма записи, в которой сначала указывается источник данных, а затем — операция.
+
+**Примеры**
+
+``` yql
+FROM my_table SELECT key, value;
+```
+
+``` yql
+FROM a_table AS a
+JOIN b_table AS b
+USING (key)
+SELECT *;
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/functional_tables.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/functional_tables.md
new file mode 100644
index 00000000000..ca2589589f6
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/functional_tables.md
@@ -0,0 +1,114 @@
+## Обращение к нескольким таблицам в одном запросе {#concat} {#each} {#range} {#like} {#filter} {#regexp}
+
+В стандартном SQL для выполнения запроса по нескольким таблицам используется [UNION ALL](#unionall), который объединяет результаты двух и более `SELECT`. Это не совсем удобно для сценария использования, в котором требуется выполнить один и тот же запрос по нескольким таблицам (например, содержащим данные на разные даты). В YQL, чтобы было удобнее, в `SELECT` после `FROM` можно указывать не только одну таблицу или подзапрос, но и вызывать встроенные функции, позволяющие объединять данные нескольких таблиц.
+
+Для этих целей определены следующие функции:
+
+```CONCAT(`table1`, `table2`, `table3` VIEW view_name, ...)``` — объединяет все перечисленные в аргументах таблицы.
+
+```EACH($list_of_strings) или EACH($list_of_strings VIEW view_name)``` — объединяет все таблицы, имена которых перечислены в списке строк. Опционально можно передать несколько списков в отдельных аргументах по аналогии с `CONCAT`.
+
+```RANGE(`prefix`, `min`, `max`, `suffix`, `view`)``` — объединяет диапазон таблиц. Аргументы:
+
+* prefix — каталог для поиска таблиц, указывается без завершающего слеша. Единственный обязательный аргумент, если указан только он, то используются все таблицы в данном каталоге.
+* min, max — следующие два аргумента задают диапазон имен для включения таблиц. Диапазон инклюзивный с обоих концов. Если диапазон не указан, используются все таблицы в каталоге prefix. Имена таблиц или директорий, находящихся в указанной в prefix директории, сравниваются с диапазоном `[min, max]` лексикографически, а не конкатенируются, таким образом важно указывать диапазон без лидирующих слешей.
+* suffix — имя таблицы. Ожидается без начального слеша. Если suffix не указан, то аргументы `[min, max]` задают диапазон имен таблиц. Если suffix указан, то аргументы `[min, max]` задают диапазон папок, в которых существует таблица с именем, указанным в аргументе suffix.
+
+```LIKE(`prefix`, `pattern`, `suffix`, `view`)``` и ```REGEXP(`prefix`, `pattern`, `suffix`, `view`)``` — аргумент pattern задается в формате, аналогичном одноименным бинарным операторам: [LIKE](../../expressions.md#like) и [REGEXP](../../expressions.md#regexp).
+
+```FILTER(`prefix`, `callable`, `suffix`, `view`)``` — аргумент callable должен являться вызываемым выражением с сигнатурой `(String)->Bool`, который будет вызван для каждой таблицы/подкаталога в каталоге prefix. В запросе будут участвовать только те таблицы, для которых вызываемое значение вернуло `true`. В качестве вызываемого значения удобнее всего использовать [лямбда функции](../../expressions.md#lambda){% if yql == true %}, либо UDF на [Python](../../../udf/python.md) или [JavaScript](../../../udf/javascript.md){% endif %}.
+
+{% note warning "Внимание" %}
+
+Порядок, в котором будут объединены таблицы, всеми вышеперечисленными функциями не гарантируется.
+
+Список таблиц вычисляется **до** запуска самого запроса. Поэтому созданные в процессе запроса таблицы не попадут в результаты функции.
+
+{% endnote %}
+
+По умолчанию схемы всех участвующих таблиц объединяются по правилам [UNION ALL](#unionall). Если объединение схем не желательно, то можно использовать функции с суффиксом `_STRICT`, например `CONCAT_STRICT` или `RANGE_STRICT`, которые работают полностью аналогично оригинальным, но считают любое расхождение в схемах таблиц ошибкой.
+
+Для указания кластера объединяемых таблиц нужно указать его перед названием функции.
+
+Все аргументы описанных выше функций могут быть объявлены отдельно через [именованные выражения](../../expressions.md#named-nodes). В этом случае в них также допустимы и простые выражения посредством неявного вызова [EvaluateExpr](../../../builtins/basic.md#evaluate_expr_atom).
+
+Имя исходной таблицы, из которой изначально была получена каждая строка, можно получить при помощи функции [TablePath()](../../../builtins/basic.md#tablepath).
+
+
+**Примеры:**
+
+``` yql
+USE some_cluster;
+SELECT * FROM CONCAT(
+ `table1`,
+ `table2`,
+ `table3`);
+```
+
+``` yql
+USE some_cluster;
+$indices = ListFromRange(1, 4);
+$tables = ListMap($indices, ($index) -> {
+ RETURN "table" || CAST($index AS String);
+});
+SELECT * FROM EACH($tables); -- идентично предыдущему примеру
+```
+
+``` yql
+USE some_cluster;
+SELECT * FROM RANGE(`my_folder`);
+```
+
+``` yql
+SELECT * FROM some_cluster.RANGE( -- Кластер можно указать перед названием функции
+ `my_folder`,
+ `from_table`,
+ `to_table`);
+```
+
+``` yql
+USE some_cluster;
+SELECT * FROM RANGE(
+ `my_folder`,
+ `from_folder`,
+ `to_folder`,
+ `my_table`);
+```
+
+``` yql
+USE some_cluster;
+SELECT * FROM RANGE(
+ `my_folder`,
+ `from_table`,
+ `to_table`,
+ ``,
+ `my_view`);
+```
+
+``` yql
+USE some_cluster;
+SELECT * FROM LIKE(
+ `my_folder`,
+ "2017-03-%"
+);
+```
+
+``` yql
+USE some_cluster;
+SELECT * FROM REGEXP(
+ `my_folder`,
+ "2017-03-1[2-4]?"
+);
+```
+
+``` yql
+$callable = ($table_name) -> {
+ return $table_name > "2017-03-13";
+};
+
+USE some_cluster;
+SELECT * FROM FILTER(
+ `my_folder`,
+ $callable
+);
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/limit_offset.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/limit_offset.md
new file mode 100644
index 00000000000..d274d6fb71b
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/limit_offset.md
@@ -0,0 +1,23 @@
+
+## LIMIT и OFFSET {#limit-offset}
+
+`LIMIT` ограничивает вывод указанным количеством строк. По умолчанию вывод не ограничен.
+
+`OFFSET` указывает отступ от начала (в строках). По умолчанию — ноль.
+
+**Примеры**
+
+``` yql
+SELECT key FROM my_table
+LIMIT 7;
+```
+
+``` yql
+SELECT key FROM my_table
+LIMIT 7 OFFSET 3;
+```
+
+``` yql
+SELECT key FROM my_table
+LIMIT 3, 7; -- эквивалентно предыдущему примеру
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/order_by.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/order_by.md
new file mode 100644
index 00000000000..b1e679c53cb
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/order_by.md
@@ -0,0 +1,20 @@
+## ORDER BY {#order-by}
+
+Сортировка результата `SELECT` по разделенному запятыми перечню критериев сортировки. В качестве критерия может выступать значение столбца, или выражение над столбцами. Не поддерживается указание порядкового номера колонки выборки (`ORDER BY N`, где `N` - номер).
+
+Направление сортировки может быть указано после каждого критерия:
+- `ASC` — по возрастанию. Применяется по умолчанию.
+- `DESC` — по убыванию.
+
+Несколько критериев сортировки будут применены слева направо.
+
+**Пример**
+
+``` yql
+SELECT key, string_column
+FROM my_table
+ORDER BY key DESC, LENGTH(string_column) ASC;
+```
+{% if feature_window_functions %}
+Ключевое слово `ORDER BY` также может использоваться в механизме [оконных функций](../../window.md).
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/sample.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/sample.md
new file mode 100644
index 00000000000..02e03a3fad2
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/sample.md
@@ -0,0 +1,41 @@
+## TABLESAMPLE и SAMPLE {#tablesample} {#sample}
+
+Построение случайной выборки из указанного во `FROM` источника данных.
+
+`TABLESAMPLE` является частью SQL стандарта и работает следующим образом:
+
+* Указывается режим работы:
+ * `BERNOULLI` означает «медленно, честно просмотрев все данные, но по-настоящему случайно»;
+ * `SYSTEM` должен использовать знание о физическом хранении данных, чтобы избежать полного их чтения частично жертвуя случайностью выборки.
+Данные разбиваются на достаточно большие блоки, и происходит сэмплирование данных блоков целиком. Для прикладных расчётов на достаточно больших таблицах результат вполне может оказаться состоятельным.
+* Размер случайной выборки указывается в процентах следом за режимом в круглых скобках.
+* Управлять размером блоков для режима `SYSTEM` можно с помощью прагмы `yt.SamplingIoBlockSize`
+* Опционально далее указывается ключевое слово `REPEATABLE` и целое число в скобках, которое будет использовано как seed для генератора псевдослучайных чисел.
+
+`SAMPLE` является более коротким алиасом, где нет сложных настроек, а размер выборки указывается в долях. На данный момент он соответствует режиму `BERNOULLI`.
+
+{% note info "Примечание" %}
+
+В режиме `BERNOULLI` при наличии ключевого слова `REPEATABLE` в seed подмешивается chunk id для каждого чанка таблицы. Поэтому выборка для разных таблиц с одинаковым содержимым может давать разные результаты.
+
+{% endnote %}
+
+**Примеры:**
+
+``` yql
+SELECT *
+FROM my_table
+TABLESAMPLE BERNOULLI(1.0) REPEATABLE(123); -- один процент таблицы
+```
+
+``` yql
+SELECT *
+FROM my_table
+TABLESAMPLE SYSTEM(1.0); -- примерно один процент таблицы
+```
+
+``` yql
+SELECT *
+FROM my_table
+SAMPLE 1.0 / 3; -- треть таблицы
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/secondary_index.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/secondary_index.md
new file mode 100644
index 00000000000..80a0fa3d35b
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/secondary_index.md
@@ -0,0 +1,29 @@
+## VIEW (INDEX) {#secondary_index}
+
+Чтобы сделать запрос `SELECT` по вторичному индексу, используйте конструкцию:
+
+``` yql
+SELECT *
+ FROM TableName VIEW IndexName
+ WHERE …
+```
+
+**Примеры**
+
+* Выбрать все поля из таблицы `series` по индексу `views_index` с условием `views >= someValue`:
+
+ ``` yql
+ SELECT series_id, title, info, release_date, views, uploaded_user_id
+ FROM series VIEW views_index
+ WHERE views >= someValue
+ ```
+
+* Сделать [`JOIN`](../../join.md) таблиц `series` и `users` c заданным полем `userName` по индексам `users_index` и `name_index` соответственно:
+
+ ``` yql
+ SELECT t1.series_id, t1.title
+ FROM series VIEW users_index AS t1
+ INNER JOIN users VIEW name_index AS t2
+ ON t1.uploaded_user_id == t2.user_id
+ WHERE t2.name == userName;
+ ```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/temporary_table.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/temporary_table.md
new file mode 100644
index 00000000000..a09425431c7
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/temporary_table.md
@@ -0,0 +1,34 @@
+
+## Явно создаваемые временные (анонимные) таблицы {#temporary-tables}
+
+В сложных многофазных запросах бывает полезно явно создать физическую временную таблицу, чтобы вручную повлиять на ход его выполнения. Для этого можно использовать имя таблицы, начинающееся на `@`. Такие таблицы называются анонимными, чтобы отличать от временных таблиц, создаваемых YT-операцией.
+
+Каждое такое имя в рамках запроса заменяется при выполнении на глобально уникальный путь к таблице во временной директории. Такие временные таблицы автоматически удаляются по завершении выполнения запроса по тем же правилам, как и создаваемые неявно.
+
+Эта функциональность позволяет не заботиться о конфликтах в путях временных таблиц между параллельно работающими операциями, а также не удалять их явно в конце запроса.
+
+**Примеры:**
+
+``` yql
+INSERT INTO @my_temp_table
+SELECT * FROM my_input_table ORDER BY value;
+
+COMMIT;
+
+SELECT * FROM @my_temp_table WHERE value = "123"
+UNION ALL
+SELECT * FROM @my_temp_table WHERE value = "456";
+```
+
+В имени временной таблицы может использоваться [именованное выражение](../../expressions.md#named-nodes):
+
+``` yql
+$tmp_name = "my_temp_table";
+
+INSERT INTO @$tmp_name
+SELECT 1 AS one, 2 AS two, 3 AS three;
+
+COMMIT;
+
+SELECT * FROM @$tmp_name;
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/union_all.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/union_all.md
new file mode 100644
index 00000000000..c29f8d70360
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/union_all.md
@@ -0,0 +1,41 @@
+## UNION ALL {#union-all}
+
+Конкатенация результатов нескольких `SELECT` (или подзапросов).
+
+Поддерживаются два режима выполнения `UNION ALL` – по именам колонок (режим по умолчанию) и по позициям колонок (соответствует стандарту ANSI SQL и включается через соответствующую [PRAGMA](../../pragma.md#positionalunionall)).
+
+В режиме "по именам" результирующая схема данных выводится по следующим правилам:
+
+{% include [union all rules](union_all_rules.md) %}
+
+Порядок выходных колонок в этом режиме выводится как наибольший общий префикс порядка входов, после чего следуют все остальные колонки в алфавитном порядке.
+Если наибольший общий префикс пуст (в том числе и из-за отсутствия порядка на одном из входов), то порядок выхода не определен.
+
+В режиме "по позициям" результирующая схема данных выводится по следующим правилам:
+* число колонок во всех входах должно быть одинаковым
+* порядок колонок во всех входах должен быть определен
+* имена результирующих колонок совпадают с именами колонок первой таблицы
+* тип результирующих колонок выводится как общий (наиболее широкий) тип из типов входных колонок стоящих на одинаковых позициях
+
+Порядок выходных колонок в этом режиме совпадает с порядком колонок первого входа.
+
+**Примеры**
+
+``` yql
+SELECT 1 AS x
+UNION ALL
+SELECT 2 AS y
+UNION ALL
+SELECT 3 AS z;
+```
+
+В результате выполнения данного запроса в режиме по-умолчанию будет сформирована выборка с тремя колонками x, y, и z. При включенной `PRAGMA PositionalUnionAll;` в выборке будет одна колонка x.
+
+
+``` yql
+PRAGMA PositionalUnionAll;
+
+SELECT 1 AS x, 2 as y
+UNION ALL
+SELECT * FROM AS_TABLE([<|x:3, y:4|>]); -- ошибка: порядок колонок в AS_TABLE не определен
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/union_all_rules.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/union_all_rules.md
new file mode 100644
index 00000000000..8bc9561e109
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/union_all_rules.md
@@ -0,0 +1,4 @@
+* в результирующую таблицу включаются все колонки, которые встречались хоть в одной из входных таблиц;
+* если колонка присутствовала не во всех входных таблицах, то ей автоматически присваивается [опциональный тип данных](../../../types/optional.md) (допускающий значение `NULL`);
+* если колонка в разных входных таблицах имела разные типы, то выводится общий тип (наиболее широкий);
+* если колонка в разных входных таблицах имела разнородный тип, например строку и число, то это считается ошибкой.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/view.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/view.md
new file mode 100644
index 00000000000..aafc026e5d3
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/view.md
@@ -0,0 +1,22 @@
+## Представления данных (VIEW) {#view}
+
+В YQL реализовано два вида представления данных:
+
+* привязанные к конкретным таблицам;
+* независимые, в которых могут использоваться произвольное число таблиц в рамках кластера.
+Оба они не являются материализованными, то есть подставляются в граф вычислений при каждом использовании.
+
+Для обращения к представлению (`VIEW`):
+
+* привязанные к таблице требуют использования специального синтаксиса: ```[cluster.]`path/to/table` VIEW view_name```;
+* независимые с точки зрения пользователя выглядят как обычные таблицы.
+
+Если в мета-атрибутах таблицы указан автоматический вызов UDF для преобразования сырых данных в структурированный набор колонок, обратиться к сырым данным можно с помощью специального представления `raw`, например ```[cluster.]`path/to/table` VIEW raw```.
+
+**Примеры:**
+
+``` yql
+USE some_cluster;
+SELECT *
+FROM my_table VIEW my_view;
+``` \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/where.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/where.md
new file mode 100644
index 00000000000..b9051dbafdf
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/where.md
@@ -0,0 +1,10 @@
+## WHERE {#where}
+
+Фильтрация строк в результате `SELECT` по условию.
+
+**Пример**
+
+``` yql
+SELECT key FROM my_table
+WHERE value > 0;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/with.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/with.md
new file mode 100644
index 00000000000..eba7215d166
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/with.md
@@ -0,0 +1,44 @@
+## WITH
+
+Задается после источника данных во `FROM` и используется для указания дополнительных подсказок использования таблиц. Подсказки нельзя задать для подзапросов и [именованных выражений](../../expressions.md#named-nodes).
+
+Поддерживаются следующие значения:
+
+* `INFER_SCHEMA` — задает флаг вывода схемы таблицы. Поведение аналогично заданию [прагмы yt.InferSchema](../../pragma.md#inferschema), только для конкретного источника данных. Можно задать число строк для выведения (число от 1 до 1000).
+* `FORCE_INFER_SCHEMA` — задает флаг вывода схемы таблицы. Поведение аналогично заданию [прагмы yt.ForceInferSchema](../../pragma.md#inferschema), только для конкретного источника данных. Можно задать число строк для выведения (число от 1 до 1000).
+* `DIRECT_READ` — подавляет работу некоторых оптимизаторов и заставляет использовать содержимое таблицы как есть. Поведение аналогично заданию отладочной [прагмы DirectRead](../../pragma.md#debug), только для конкретного источника данных.
+* `INLINE` — указание на то, что содержимое таблицы небольшое и нужно использовать его представление в памяти для обработки запроса. Реальный объем таблицы при этом не контролируется, и если он большой, то запрос может упасть по превышению памяти.
+* `UNORDERED` — подавляет использование исходной сортировки таблицы.
+* `XLOCK` — указание на то, что нужно брать эксклюзивный лок на таблицу. Полезен, когда чтение таблицы происходит на стадии обработки [метапрограммы запроса](../../action.md), а затем ее содержимое обновляется в основном запросе. Позволяет избежать потери данных, если между исполнением фазы метапрограммы и основной частью запроса внешний процесс успел изменить таблицу.
+* `SCHEMA` type — указание на то, что следует использовать указанную схему таблицы целиком, игнорируя схему в метаданных.
+* `COLUMNS` type — указание на то, что следует использовать указанные типы для колонок, чьи имена совпадают с именами колонок таблицы в метаданных, а также какие колонки дополнительно присутствуют в таблице.
+* `IGNORETYPEV3`, `IGNORE_TYPE_V3` — задает флаг игнорирования type_v3 типов в таблице. Поведение аналогично заданию [прагмы yt.IgnoreTypeV3](../../pragma.md#ignoretypev3), только для конкретного источника данных.
+
+При задании подсказок `SCHEMA` и `COLUMNS` в качестве значения типа type должен быть задан тип [структуры](../../../types/containers.md).
+Если задана подсказка `SCHEMA`, то при использовании табличных функций [EACH](#each), [RANGE](#range), [LIKE](#like), [REGEXP](#regexp), [FILTER](#filter) допускается пустой список таблиц, который обрабатывается как пустая таблица с колонками, описанными в `SCHEMA`.
+
+**Примеры:**
+
+``` yql
+SELECT key FROM my_table WITH INFER_SCHEMA;
+SELECT key FROM my_table WITH FORCE_INFER_SCHEMA="42";
+```
+
+``` yql
+$s = (SELECT COUNT(*) FROM my_table WITH XLOCK);
+
+INSERT INTO my_table WITH TRUNCATE
+SELECT EvaluateExpr($s) AS a;
+```
+
+``` yql
+SELECT key, value FROM my_table WITH SCHEMA Struct<key:String, value:Int32>;
+```
+
+``` yql
+SELECT key, value FROM my_table WITH COLUMNS Struct<value:Int32?>;
+```
+
+``` yql
+SELECT key, value FROM EACH($my_tables) WITH SCHEMA Struct<key:String, value:List<Int32>>;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/without.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/without.md
new file mode 100644
index 00000000000..eae2952caff
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select/without.md
@@ -0,0 +1,15 @@
+## WITHOUT {#without}
+
+Исключение столбцов из результата `SELECT *`.
+
+**Примеры**
+
+``` yql
+SELECT * WITHOUT foo, bar FROM my_table;
+```
+
+``` yql
+PRAGMA simplecolumns;
+SELECT * WITHOUT t.foo FROM my_table AS t
+CROSS JOIN (SELECT 1 AS foo) AS v;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select_stream.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select_stream.md
new file mode 100644
index 00000000000..18308176ceb
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/select_stream.md
@@ -0,0 +1,45 @@
+# SELECT STREAM ... FROM
+
+Для работы со стримами RTMR необходимо использовать конструкцию `SELECT STREAM` вместо `SELECT` для обычных таблиц в других системах. `FROM` используется для указания источника данных. Как правило, в качестве аргумента `FROM` выступает имя стрима, который ищется в кластере, заданном оператором [USE](../use.md), но может использоваться и результат другого `SELECT STREAM` (подзапрос). Также стрим можно указать через [именованное выражение](../expressions.md#named-nodes), содержащее строку.
+
+В выражениях между `SELECT STREAM` и `FROM` можно указывать имена столбцов из источника (через запятую). Специальный символ `*` в этой позиции обозначает «все столбцы».
+
+**Примеры:**
+``` yql
+SELECT STREAM key FROM my_stream;
+```
+
+``` yql
+SELECT STREAM * FROM
+ (SELECT STREAM value FROM my_stream);
+```
+
+``` yql
+$stream_name = "my_" || "stream";
+SELECT STREAM * FROM $stream_name;
+```
+
+## WHERE
+
+Фильтрация строк в результате `SELECT STREAM` по условию.
+
+**Примеры:**
+``` yql
+SELECT STREAM key FROM my_stream
+WHERE value > 0;
+```
+
+## UNION ALL
+
+Конкатенация результатов нескольких `SELECT STREAM`, их схемы объединяются по следующим правилам:
+
+{% include [union all rules](../_includes/select/union_all_rules.md) %}
+
+**Примеры:**
+``` yql
+SELECT STREAM x FROM my_stream_1
+UNION ALL
+SELECT STREAM y FROM my_stream_2
+UNION ALL
+SELECT STREAM z FROM my_stream_3
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/subquery.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/subquery.md
new file mode 100644
index 00000000000..19dc69643f8
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/subquery.md
@@ -0,0 +1,199 @@
+# Шаблоны подзапросов (subquery)
+
+## DEFINE SUBQUERY {#define-subquery}
+
+`DEFINE SUBQUERY` позволяет объявить шаблон подзапроса (subquery), который представляет собой параметризуемый блок из нескольких выражений верхнего уровня (statements), и затем многократно его использовать путем применения в секции `FROM` выражения [SELECT](../select.md){% if feature_mapreduce %} или входных данных в [PROCESS](../process.md)/[REDUCE](../reduce.md){% endif %} с указанием параметров.
+В отличие от [действий](../action.md) шаблон подзапроса должен заканчиваться выражением `SELECT`{% if feature_mapreduce %}/`PROCESS`/`REDUCE`{% endif %}, чей результат и является возвращаемым значением подзапроса. При этом выражение верхнего уровня `SELECT`{% if feature_mapreduce %}/`PROCESS`/`REDUCE`{% endif %} нельзя использовать более одного раза, как и модифицирующие выражения (например, `INSERT`).
+
+ После `DEFINE SUBQUERY` указывается:
+
+1. [Именованное выражение](../expressions.md#named-nodes), по которому объявляемый шаблон будет доступен далее в запросе;
+2. В круглых скобках список именованных выражений, по которым внутри шаблона подзапроса можно обращаться к параметрам;
+3. Ключевое слово `AS`;
+4. Сам список выражений верхнего уровня;
+5. `END DEFINE` выступает в роли маркера, обозначающего последнее выражение внутри шаблона подзапроса.
+
+Один или более последних параметров subquery могут быть помечены вопросиком как необязательные — если они не были указаны при вызове subquery, то им будет присвоено значение `NULL`.
+
+{% if feature_mapreduce %}
+
+{% note info "Примечание" %}
+
+В больших запросах объявление шаблонов подзапросов можно выносить в отдельные файлы и подключать их в основной запрос с помощью [EXPORT](../export_import.md#export) + [IMPORT](../export_import.md#import), чтобы вместо одного длинного текста получилось несколько логических частей, в которых проще ориентироваться. Важный нюанс: директива `USE my_cluster;` в импортирующем запросе не влияет на поведение объявленных в других файлах подзапросов.
+
+{% endnote %}
+
+{% endif %}
+
+Даже если список параметров в определении шаблона подзапроса пустой при использовании его во `FROM` секции нужно указать скобки `()`. Такое может быть удобно использовать, чтобы ограничить область видимости именованных выражений, используемых только в одном подзапросе.
+
+{% if feature_mapreduce %}
+В некоторых случаях вместо операции `DEFINE SUBQUERY` удобнее использовать эквивалентную форму в виде [лямбда функции](../expressions.md#lambda).
+В этом случае лямбда функция должна принимать первым аргументом специальный объект `world`, через который передаются зависимости о том, какие видны PRAGMA или COMMIT в точке использования шаблона запроса. Также этот объект нужно передавать первым аргументом вместе с остальными аргументами при их наличии другим шаблонам запросов, если они используются в лямбда функции.
+Возвращаемым значением лямбда функции должно быть значение с типом список структур (выходная таблица) или список вариантов над кортежом из структур (несколько выходных таблиц). В последнем случае в точке использования шаблона запроса обычно используется распаковка вида
+
+```yql
+$out1, $out2 = PROCESS $mySubquery($myParam1, $myParam2);
+-- используем далее $out1 и $out2 как отдельные таблицы.
+```
+
+{% endif %}
+
+**Примеры**
+
+``` yql
+DEFINE SUBQUERY $hello_world($name, $suffix?) AS
+ $name = $name ?? ($suffix ?? "world");
+ SELECT "Hello, " || $name || "!";
+END DEFINE;
+
+SELECT * FROM $hello_world(NULL); -- Hello, world!
+SELECT * FROM $hello_world("John"); -- Hello, John!
+SELECT * FROM $hello_world(NULL, "Earth"); -- Hello, Earth!
+```
+
+```yql
+DEFINE SUBQUERY $dup($x) AS
+ SELECT * FROM $x(1) -- применяем переданный шаблон запроса с одним аргументом
+ UNION ALL
+ SELECT * FROM $x(2); -- ... и с другим аргументом
+END DEFINE;
+
+DEFINE SUBQUERY $sub($n) AS
+ SELECT $n * 10;
+END DEFINE;
+
+SELECT * FROM $dup($sub); -- передаем шаблон запроса $sub как параметр
+-- Результат:
+-- 10
+-- 20
+```
+
+```yql
+/* Уберем используемые именованные выражения $a и $b в отдельную область видимости */
+DEFINE SUBQUERY $clean() AS
+ $a = 10;
+ $b = $a * $a;
+ SELECT $a AS a, $b AS b;
+END DEFINE;
+
+SELECT * FROM $clean(); -- a: 10, b: 100
+```
+
+{% if feature_mapreduce %}
+```yql
+USE hahn;
+
+DEFINE SUBQUERY $input() as
+ SELECT * FROM `home/yql/tutorial/users`;
+END DEFINE;
+
+DEFINE SUBQUERY $myProcess1($nestedQuery, $lambda) AS
+ PROCESS $nestedQuery() -- использование скобок () тут обязательно
+ USING $lambda(TableRow());
+END DEFINE;
+
+$myProcess2 = ($world, $nestedQuery, $lambda) -> {
+ -- Если использовать ListFlatMap или YQL::OrderedFlatMap, то получится Ordered YT Map операция
+ return YQL::FlatMap($nestedQuery($world), $lambda);
+};
+
+-- При таком использовании реализации $myProcess1 и $myProcess2 идентичны
+SELECT * FROM $myProcess1($input, ($x) -> { RETURN AsList($x, $x) });
+SELECT * FROM $myProcess2($input, ($x) -> { RETURN AsList($x, $x) });
+```
+
+```yql
+USE hahn;
+
+DEFINE SUBQUERY $runPartition($table) AS
+ $paritionByAge = ($row) -> {
+ $recordType = TypeOf($row);
+ $varType = VariantType(TupleType($recordType, $recordType));
+ RETURN If($row.age % 2 == 0,
+ Variant($row, "0", $varType),
+ Variant($row, "1", $varType),
+ );
+ };
+
+ PROCESS $table USING $paritionByAge(TableRow());
+END DEFINE;
+
+-- Распаковка двух результатов
+$i, $j = (PROCESS $runPartition("home/yql/tutorial/users"));
+
+SELECT * FROM $i;
+
+SELECT * FROM $j;
+```
+{% endif %}
+
+## Объединение шаблонов подзапросов SubqueryExtend, SubqueryUnionAll, SubqueryMerge, SubqueryUnionMerge {#subquery-extend} {#subquery-unionall} {#subquery-merge} {#subquery-unionmerge}
+
+Эти функции объединяют результаты одного и более шаблонов подзапросов, переданных аргументами. Требуется совпадение количества параметров в этих шаблонах подзапросов.
+
+* `SubqueryExtend` требует совпадение схем подзапросов;
+* `SubqueryUnionAll` работает по тем же правилам, что и [ListUnionAll](../../builtins/list.md#ListUnionAll);
+* `SubqueryMerge` использует те же ограничения, что и `SubqueryExtend`, а также выдает сортированный результат в случае если все подзапросы одинаково отсортированны;
+* `SubqueryUnionMerge` использует те же ограничения, что и `SubqueryUnionAll`, а также выдает сортированный результат в случае если все подзапросы одинаково отсортированны.
+
+**Примеры:**
+
+```yql
+DEFINE SUBQUERY $sub1() as
+ SELECT 1 as x;
+END DEFINE;
+
+DEFINE SUBQUERY $sub2() as
+ SELECT 2 as x;
+END DEFINE;
+
+$s = SubqueryExtend($sub1,$sub2);
+PROCESS $s();
+```
+
+## Объединение шаблонов подзапросов после подстановки элемента списка SubqueryExtendFor, SubqueryUnionAllFor, SubqueryMergeFor, SubqueryUnionMergeFor {#subquery-extend-for} {#subquery-unionall-for} {#subquery-merge-for} {#subquery-unionmerge-for}
+
+Эти функции принимают аргументы:
+
+* Непустой список значений;
+* Шаблон подзапроса, в котором должен быть ровно один параметр.
+
+И выполняют подстановку в шаблон подзапроса в качестве параметра каждый элемент из списка, после чего объединяют полученные подзапросы.
+
+* `SubqueryExtendFor` требует совпадение схем подзапросов;
+* `SubqueryUnionAllFor` работает по тем же правилам, что и [ListUnionAll](../../builtins/list.md#ListUnionAll);
+* `SubqueryMergeFor` использует те же ограничения, что и `SubqueryExtendFor`, а также выдает сортированный результат в случае если все подзапросы одинаково отсортированны;
+* `SubqueryUnionMergeFor` использует те же ограничения, что и `SubqueryUnionAllFor`, а также выдает сортированный результат в случае если все подзапросы одинаково отсортированны.
+
+**Примеры:**
+
+```yql
+DEFINE SUBQUERY $sub($i) as
+ SELECT $i as x;
+END DEFINE;
+
+$s = SubqueryExtendFor([1,2,3],$sub);
+PROCESS $s();
+```
+
+## Добавление сортировки в шаблон подзапроса SubqueryOrderBy или указание о наличии таковой SubqueryAssumeOrderBy
+
+Эти функции принимают аргументы:
+
+* Шаблон подзапроса без параметров;
+* Список пар (строка - имя колонки, булево значение - true для сортировки по возрастанию или false для сортировки по убыванию.
+
+И выполняют построение нового шаблона запроса без параметров, в котором выполняется сортировка или добавляется указание о наличии сортировки к результату. Для использования полученного шаблона запроса необходимо использовать функцию `PROCESS`, так как при использовании `SELECT` сортировка будет проигнорирована.
+
+**Примеры:**
+
+```yql
+DEFINE SUBQUERY $sub() as
+ SELECT * FROM (VALUES (1,'c'), (1,'a'), (3,'b')) AS a(x,y);
+end define;
+
+$sub2 = SubqueryOrderBy($sub, [('x',false), ('y',true)]);
+
+PROCESS $sub2();
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/update.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/update.md
new file mode 100644
index 00000000000..3dde2ff42f7
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/update.md
@@ -0,0 +1,37 @@
+# UPDATE
+
+Изменяет данные в таблице.{% if feature_mapreduce %} Таблица по имени ищется в базе данных, заданной оператором [USE](../use.md).{% endif %} После ключевого слова `SET` указываются столбцы, значение которых необходимо заменить, и сами новые значения. Список строк задается с помощью условия `WHERE`. Если `WHERE` отсутствует, изменения будут применены ко всем строкам таблицы.
+
+`UPDATE` не может менять значение `PRIMARY_KEY`.
+
+{% note info %}
+
+Изменение состояния таблицы не отслеживается в рамках одной транзакции. Если таблица уже была изменена, для обновления данных в той же транзакции используйте [`UPDATE ON`](#update-on).
+
+{% endnote %}
+
+**Пример**
+
+```sql
+UPDATE my_table
+SET Value1 = YQL::ToString(Value2 + 1), Value2 = Value2 - 1
+WHERE Key1 > 1;
+```
+
+## UPDATE ON {#update-on}
+
+Используется для обновления данных, если таблица уже была изменена ранее, в рамках одной транзакции.
+
+**Пример**
+
+```sql
+$to_update = (
+ SELECT Key, SubKey, "Updated" AS Value FROM my_table
+ WHERE Key = 1
+);
+
+SELECT * FROM my_table;
+
+UPDATE my_table ON
+SELECT * FROM $to_update;
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/upsert_into.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/upsert_into.md
new file mode 100644
index 00000000000..67df2be227e
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/upsert_into.md
@@ -0,0 +1,26 @@
+# UPSERT INTO
+
+Добавляет или обновляет множество строк в таблице на основании сравнения по первичному ключу. Отсутствующие строки добавляются. В присутствующих строках обновляются значения заданных столбцов, значения остальных столбцов остаются неизменными.
+
+{% if feature_mapreduce %} Таблица по имени ищется в базе данных, заданной оператором [USE](../use.md).{% endif %}
+
+{% if feature_replace %}
+`UPSERT` и [`REPLACE`](../replace_into.md) являются операциями модификации данных, которые не требует их предварительного чтения, за счет чего работают быстрее и дешевле других операций.
+{% else %}
+`UPSERT` является единственной операцией модификации данных, которая не требует их предварительного чтения, за счет чего работает быстрее и дешевле других операций.
+{% endif %}
+
+Сопоставление столбцов при использовании `UPSERT INTO ... SELECT` производится по именам. Используйте `AS` для получения колонки с нужным именем в `SELECT`.
+
+**Примеры**
+
+``` yql
+UPSERT INTO my_table
+SELECT pk_column, data_column1, col24 as data_column3 FROM other_table
+```
+
+``` yql
+UPSERT INTO my_table ( pk_column1, pk_column2, data_column2, data_column5 )
+VALUES ( 1, 10, 'Some text', Date('2021-10-07')),
+ ( 2, 10, 'Some text', Date('2021-10-08'))
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/use.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/use.md
new file mode 100644
index 00000000000..1693ae24d61
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/use.md
@@ -0,0 +1,23 @@
+# USE
+
+Указать «базу данных». Как правило, в её роли выступает один из кластеров {{ backend_name }}. Это указание будет использоваться по умолчанию для поиска таблиц в тех случаях, где база данных не указана явно.
+
+Если в запросе не используется `USE`, то кластер следует указывать в начале пути к таблице в формате ``` cluster.`path/to/table` ```, например ``` hahn.`home/yql/test` ```. Backticks используются для автоматического экранирования спецсимволов, в данном случае слешей.
+
+Обычно имя кластера указывается непосредственно, но есть возможность указать его в виде выражения. В частности, это позволит использовать параметры, объявленные через [DECLARE](../declare.md).
+В этом случае для `USE` должна использоваться запись ```USE yt:$cluster_name```, где `$cluster_name` - [именованное выражение](../expressions.md#named-nodes) типа `String`.
+Либо можно указывать кластер прямо в начале пути к таблице в формате ``` yt:$cluster_name.`path/to/table` ```.
+
+Сам `USE` при этом можно использовать внутри [действий](../action.md){% if feature_subquery %} или [шаблонов подзапросов](../subquery.md){% endif %}. Значение текущего кластера наследуется на объявления вложенных действий{% if feature_subquery %} или подзапросов{% endif %}. Область влияния `USE` прекращается по окончании действия{% if feature_subquery %} или шаблона подзапроса{% endif %}, в котором оно объявлено.
+
+**Примеры:**
+
+``` yql
+USE {{ example_cluster }};
+```
+
+{% note info "Примечание" %}
+
+`USE` **не** гарантирует, что запрос обязательно будет выполнен именно на указанном кластере. Запрос может быть выполнен на другом кластере, если в нем не используются входные данные (например, `USE foo; SELECT 2 + 2;` ) или если указан полный путь к таблице на другом кластере (например, `USE foo; SELECT * FROM bar.``path/to/table``;`).
+
+{% endnote %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/values.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/values.md
new file mode 100644
index 00000000000..fd12d7d6476
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/values.md
@@ -0,0 +1,43 @@
+# Базовый синтаксис VALUES в YQL
+
+## VALUES как оператор верхнего уровня
+
+Позволяет сформировать таблицу из указанных значений. Например, данное выражение формирует таблицу из k колонок и n строк:
+``` yql
+VALUES (expr_11, expr_12, ..., expr_1k),
+ (expr_21, expr_22, ..., expr_2k),
+ ....
+ (expr_n1, expr_n2, ..., expr_nk);
+
+```
+
+Это выражение полностью эквивалентно следующему:
+
+``` yql
+SELECT expr_11, expr_12, ..., expr_1k UNION ALL
+SELECT expr_21, expr_22, ..., expr_2k UNION ALL
+....
+SELECT expr_n1, expr_n2, ..., expr_nk;
+
+```
+
+**Пример:**
+
+``` yql
+VALUES (1,2), (3,4);
+```
+
+
+## VALUES после FROM
+
+VALUES может использоваться и в подзапросе после FROM. В частности, эти два запроса эквивалентны:
+``` yql
+VALUES (1,2), (3,4);
+SELECT * FROM (VALUES (1,2), (3,4));
+```
+
+Во всех примерах выше имена колонок назначаются YQL и имеют вид `column0 ... columnN`. Для того, чтобы назначить произвольные имена колонок, можно воспользоваться следующей конструкцией:
+``` yql
+SELECT * FROM (VALUES (1,2), (3,4)) as t(x,y);
+```
+В данном случае колонки получат имена `x`, `y`.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/window.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/window.md
new file mode 100644
index 00000000000..b3613fadc5d
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/_includes/window.md
@@ -0,0 +1,152 @@
+# OVER, PARTITION BY и WINDOW
+
+Механизм оконных функций, появившийся в стандарте SQL:2003 и расширенный в стандарте SQL:2011, позволяет выполнять вычисления над набором строк таблицы, который некоторым образом соотносится с текущей строкой.
+
+В отличие от [агрегатных функций](../../builtins/aggregation.md) при этом не происходит группировка нескольких строк в одну – после применения оконных функций число строк в результирующей таблице всегда совпадает с числом строк в исходной.
+
+При наличии в запросе агрегатных и оконных функций сначала производится группировка и вычисляются значения агрегатных функций. Вычисленные значения агрегатных функций могут использоваться в качестве аргументов оконных (но не наоборот).
+
+## Синтаксис {#syntax}
+
+Общий синтаксис вызова оконной функции имеет вид
+```
+function_name([expression [, expression ...]]) OVER (window_definition)
+или
+function_name([expression [, expression ...]]) OVER window_name
+```
+
+Здесь `window_name` (_имя окна_) – произвольный идентификатор, уникальный в рамках запроса, `expression` – произвольное выражение не содержащее вызова оконных функций.
+
+В запросе каждому имени окна должно быть сопоставлено _определение окна_ (`window_definition`):
+
+```
+SELECT
+ F0(...) OVER (window_definition_0),
+ F1(...) OVER w1,
+ F2(...) OVER w2,
+ ...
+FROM my_table
+WINDOW
+ w1 AS (window_definition_1),
+ ...
+ w2 AS (window_definition_2)
+;
+```
+
+Здесь `window_definition` записывается в виде
+```
+[ PARTITION BY (expression AS column_identifier | column_identifier) [, ...] ]
+[ ORDER BY expression [ASC | DESC] ]
+[ frame_definition ]
+```
+
+Необязательное *определение рамки* (`frame_definition`) может быть задано одним из двух способов:
+
+* ```ROWS frame_begin```
+* ```ROWS BETWEEN frame_begin AND frame_end```
+
+*Начало рамки* (`frame_begin`) и *конец рамки* (`frame_end`) задаются одним из следующих способов:
+
+* ```UNBOUNDED PRECEDING```
+* ```offset PRECEDING```
+* ```CURRENT ROW```
+* ```offset FOLLOWING```
+* ```UNBOUNDED FOLLOWING```
+
+Здесь *смещение рамки* (`offset`) – неотрицательный числовой литерал. Если конец рамки не задан, то подразумевается `CURRENT ROW`.
+
+Все выражения внутри определения окна не должны содержать вызовов оконных функций.
+
+## Алгоритм вычисления
+
+### Разбиение {#partition}
+Указание `PARTITION BY` группирует строки исходной таблицы в _разделы_, которые затем обрабатываются независимо друг от друга.
+Если `PARTITION BY` не указан, то все строки исходной таблицы попадают в один раздел. Указание `ORDER BY` определяет порядок строк в разделе.
+В `PARTITION BY`, как и в [GROUP BY](../group_by.md) можно использовать алиасы и [SessionWindow](../group_by.md#session-window).
+
+При отсутствии `ORDER BY` порядок строк в разделе не определен.
+
+### Рамка {#frame}
+Определение рамки `frame_definition` задает множество строк раздела, попадающих в *рамку окна* связанную с текущей строкой.
+
+В режиме `ROWS` (в YQL пока поддерживается только он) в рамку окна попадают строки с указанными смещениями относительно текущей строки раздела.
+
+ * Например, для `ROWS BETWEEN 3 PRECEDING AND 5 FOLLOWING` в рамку окна попадут три строки перед текущей, текущая строка и пять строк после текущей строки.
+
+Множество строк в рамке окна может меняться в зависимости от того, какая строка является текущей.
+
+ * Например, для первой строки раздела в рамку окна `ROWS BETWEEN 3 PRECEDING AND 1 PRECEDING` не попадет ни одной строки.
+
+Указание `UNBOUNDED PRECEDING` в качестве начала рамки означает "от первой строки раздела", `UNBOUNDED FOLLOWING` в качестве конца рамки – "до последней строки раздела", `CURRENT ROW` – "от/до текущей строки".
+
+Если `определение_рамки` не указано, то в множество строк попадающих в рамку окна определяется наличием `ORDER BY` в `определении_окна`.
+А именно, при наличии `ORDER BY` неявно подразумевается `ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`, а при отсутствии – `ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING`.
+
+Далее, в зависимости от конкретной оконной функции производится ее вычисление либо на множестве строк раздела, либо на множестве строк рамки окна.
+
+[Список доступных оконных функций](../../builtins/window.md)
+
+**Примеры:**
+
+```sql
+SELECT
+ COUNT(*) OVER w AS rows_count_in_window,
+ some_other_value -- доступ к текущей строке
+FROM `my_table`
+WINDOW w AS (
+ PARTITION BY partition_key_column
+ ORDER BY int_column
+);
+```
+
+```sql
+SELECT
+ LAG(my_column, 2) OVER w AS row_before_previous_one
+FROM `my_table`
+WINDOW w AS (
+ PARTITION BY partition_key_column
+);
+```
+
+``` yql
+SELECT
+ -- AVG (как и все агрегатные функции, используемые в качестве оконных)
+ -- вычисляется на рамке окна
+ AVG(some_value) OVER w AS avg_of_prev_current_next,
+ some_other_value -- доступ к текущей строке
+FROM my_table
+WINDOW w AS (
+ PARTITION BY partition_key_column
+ ORDER BY int_column
+ ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING
+);
+```
+
+``` yql
+SELECT
+ -- LAG не зависит от положения рамки окна
+ LAG(my_column, 2) OVER w AS row_before_previous_one
+FROM my_table
+WINDOW w AS (
+ PARTITION BY partition_key_column
+ ORDER BY my_column
+);
+```
+
+## Особенности реализации
+
+* Функции, вычисляемые на рамке окна `ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING` либо `ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`, реализованы эффективно (не требуют дополнительной памяти и вычисляются на разделе за O(размер раздела)).
+
+* Для рамки окна `ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING` есть возможность выбрать стратегию выполнения в оперативной памяти, указав хинт `COMPACT` после ключевого слова `PARTITION`.
+
+ Например: `PARTITION COMPACT BY key` или `PARTITION COMPACT BY ()` (в случае если `PARTITION BY` изначально отсутствовал).
+
+ При наличии хинта `COMPACT` потребуется дополнительная память в размере O(размер раздела), но при этом не возникнет дополнительной `JOIN` операции.
+
+* Если рамка окна не начинается с `UNBOUNDED PRECEDING`, то для вычисления оконных функций на таком окне потребуется дополнительная память в размере O(максимальное расстояние от границ окна до текущей строки), а время вычисления будет равно O(число_строк_в_разделе * размер_окна).
+
+* Для рамки окна, начинающейся с `UNBOUNDED PRECEDING` и заканчивающейся на `N`, где `N` не равен `CURRENT ROW` или `UNBOUNDED FOLLOWING`, потребуется дополнительная память в размере O(N), а время вычисления будет O(N * число_строк_в_разделе).
+
+* Функции `LEAD(expr, N)` и `LAG(expr, N)` всегда потребуют O(N) памяти.
+
+Учитывая вышесказанное, запрос с `ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING` по возможности стоит переделать в `ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW`, поменяв порядок сортировки в `ORDER BY` на обратный.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/action.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/action.md
new file mode 100644
index 00000000000..2ddce04ead2
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/action.md
@@ -0,0 +1,11 @@
+# ACTION
+
+{% include [x](_includes/action/define_do.md) %}
+
+{% include [x](_includes/action/begin.md) %}
+
+{% if feature_mapreduce %}
+
+ {% include [x](_includes/action/evaluate.md) %}
+
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/alter_table.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/alter_table.md
new file mode 100644
index 00000000000..a6134ef7ede
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/alter_table.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/alter_table.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/create_table.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/create_table.md
new file mode 100644
index 00000000000..afc4f96ab9e
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/create_table.md
@@ -0,0 +1 @@
+{% include [x](_includes/create_table.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/declare.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/declare.md
new file mode 100644
index 00000000000..c3b29c2de89
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/declare.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/declare/general.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/delete.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/delete.md
new file mode 100644
index 00000000000..152f774f9f8
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/delete.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/delete.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/discard.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/discard.md
new file mode 100644
index 00000000000..e00213ace76
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/discard.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/discard.md) %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/drop_table.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/drop_table.md
new file mode 100644
index 00000000000..d708dc5d9ef
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/drop_table.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/drop_table.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/export_import.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/export_import.md
new file mode 100644
index 00000000000..874d843a7b7
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/export_import.md
@@ -0,0 +1,2 @@
+{% include [x](_includes/export_import.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/expressions.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/expressions.md
new file mode 100644
index 00000000000..559b6743c1f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/expressions.md
@@ -0,0 +1,32 @@
+# Выражения
+
+{% include [x](_includes/expressions/concatenation.md) %}
+
+{% include [x](_includes/expressions/check-match.md) %}
+
+{% include [x](_includes/expressions/operators.md) %}
+
+{% include [x](_includes/expressions/is-null.md) %}
+
+{% include [x](_includes/expressions/is-distinct-from.md) %}
+
+{% include [x](_includes/expressions/between.md) %}
+
+{% include [x](_includes/expressions/in.md) %}
+
+{% include [x](_includes/expressions/as.md) %}
+
+{% include [x](_includes/expressions/cast.md) %}
+
+{% include [x](_includes/expressions/bitcast.md) %}
+
+{% include [x](_includes/expressions/case.md) %}
+
+{% include [x](_includes/expressions/named-nodes.md) %}
+
+{% include [x](_includes/expressions/tables.md) %}
+
+{% include [x](_includes/expressions/lambda.md) %}
+
+{% include [x](_includes/expressions/items-access.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/flatten.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/flatten.md
new file mode 100644
index 00000000000..4068bae5b7e
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/flatten.md
@@ -0,0 +1,7 @@
+{% include [x](_includes/flatten/flatten_by.md) %}
+
+{% include [x](_includes/flatten/flatten_type_by.md) %}
+
+{% include [x](_includes/flatten/flatten_other_db.md) %}
+
+{% include [x](_includes/flatten/flatten_columns.md) %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/group_by.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/group_by.md
new file mode 100644
index 00000000000..b68596578bb
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/group_by.md
@@ -0,0 +1,27 @@
+{% if select_command == "SELECT STREAM" %}
+
+ {% include [x](_includes/group_by/general_stream.md) %}
+
+ {% include [x](_includes/group_by/having_stream.md) %}
+
+{% else %}
+
+{% include [x](_includes/group_by/general.md) %}
+
+{% include [x](_includes/group_by/session_window.md) %}
+
+{% if feature_group_by_rollup_cube %}
+
+ {% include [x](_includes/group_by/rollup_cube_sets.md) %}
+
+{% endif %}
+
+{% include [x](_includes/group_by/distinct.md) %}
+
+{% include [x](_includes/group_by/compact.md) %}
+
+{% include [x](_includes/group_by/having.md) %}
+
+{% endif %}
+
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/index.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/index.md
new file mode 100644
index 00000000000..0cf7919f745
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/index.md
@@ -0,0 +1,55 @@
+# Список статей по синтаксису YQL
+
+* [Лексическая структура](lexer.md)
+* [Выражения](expressions.md)
+{% if feature_mapreduce %}
+* [USE](use.md)
+{% endif %}
+* [SELECT](select.md)
+* [VALUES](values.md)
+{% if select_command == "SELECT STREAM" %}
+* [SELECT STREAM](select_stream.md)
+{% endif %}
+* [CREATE TABLE](create_table.md)
+* [DROP TABLE](drop_table.md)
+* [INSERT](insert_into.md)
+{% if feature_map_tables %}
+* [UPDATE](update.md)
+* [DELETE](delete.md)
+{% endif %}
+{% if feature_replace %}
+* [REPLACE](replace_into.md)
+{% endif %}
+{% if feature_upsert %}
+* [UPSERT](upsert_into.md)
+{% endif %}
+* [GROUP BY](group_by.md)
+{% if feature_join %}
+* [JOIN](join.md)
+{% endif %}
+{% if feature_window_functions %}
+* [WINDOW](window.md)
+{% endif %}
+* [FLATTEN](flatten.md)
+* [ACTION](action.md)
+{% if feature_mapreduce and process_command == "PROCESS" %}
+* [SUBQUERY](subquery.md)
+{% endif %}
+* [DISCARD](discard.md)
+* [INTO RESULT](into_result.md)
+{% if feature_mapreduce %}
+{% if process_command == "PROCESS" %}
+* [PROCESS](process.md)
+{% endif %}
+{% if process_command == "PROCESS STREAM" %}
+* [PROCESS STREAM](process.md)
+{% endif %}
+{% if reduce_command == "REDUCE" %}
+* [REDUCE](reduce.md)
+{% endif %}
+{% endif %}
+* [PRAGMA](pragma.md)
+* [DECLARE](declare.md)
+{% if feature_mapreduce %}
+* [EXPORT и IMPORT](export_import.md)
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/insert_into.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/insert_into.md
new file mode 100644
index 00000000000..e78e03e820d
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/insert_into.md
@@ -0,0 +1,4 @@
+
+{% include [x](_includes/insert_into.md) %}
+
+{% include [x](_includes/insert_hints.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/into_result.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/into_result.md
new file mode 100644
index 00000000000..a4fa2e247ef
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/into_result.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/into_result.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/join.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/join.md
new file mode 100644
index 00000000000..cbef5bb3693
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/join.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/join.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/lexer.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/lexer.md
new file mode 100644
index 00000000000..1b753402103
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/lexer.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/lexer.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/not_yet_supported.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/not_yet_supported.md
new file mode 100644
index 00000000000..4022cb3aeac
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/not_yet_supported.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/not_yet_supported.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/pragma.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/pragma.md
new file mode 100644
index 00000000000..5249455c7d3
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/pragma.md
@@ -0,0 +1,13 @@
+# PRAGMA
+
+{% include [x](_includes/pragma/definition.md) %}
+
+{% include [x](_includes/pragma/global.md) %}
+
+{% include [x](_includes/pragma/yson.md) %}
+
+{% include [x](_includes/pragma/files.md) %}
+
+{% include [x](_includes/pragma/ydb.md) %}
+
+{% include [x](_includes/pragma/debug.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/process.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/process.md
new file mode 100644
index 00000000000..7ea4f9e2b30
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/process.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/process.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/reduce.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/reduce.md
new file mode 100644
index 00000000000..5885c8354c6
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/reduce.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/reduce.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/replace_into.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/replace_into.md
new file mode 100644
index 00000000000..96d50060b27
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/replace_into.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/replace_into.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/select.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/select.md
new file mode 100644
index 00000000000..951d674a5c4
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/select.md
@@ -0,0 +1,53 @@
+# Синтаксис SELECT
+
+<!-- File split by includable blocks as part of YQL docs preparation for YQL/YDB opensource -->
+
+{% include [x](_includes/select/calc.md) %}
+
+{% include [x](_includes/select/from.md) %}
+
+{% if feature_secondary_index %}
+
+ {% include [x](_includes/select/secondary_index.md) %}
+
+{% endif %}
+
+{% include [x](_includes/select/with.md) %}
+
+{% include [x](_includes/select/where.md) %}
+
+{% include [x](_includes/select/order_by.md) %}
+
+{% include [x](_includes/select/limit_offset.md) %}
+
+{% include [x](_includes/select/assume_order_by.md) %}
+
+{% include [x](_includes/select/sample.md) %}
+
+{% include [x](_includes/select/distinct.md) %}
+
+{% include [x](_includes/select/execution.md) %}
+
+{% include [x](_includes/select/column_order.md) %}
+
+{% include [x](_includes/select/union_all.md) %}
+
+{% include [x](_includes/select/commit.md) %}
+
+{% if feature_bulk_tables %}
+
+ {% include [x](_includes/select/functional_tables.md) %}
+
+ {% include [x](_includes/select/folder.md) %}
+
+{% endif %}
+
+{% include [x](_includes/select/without.md) %}
+
+{% include [x](_includes/select/from_select.md) %}
+
+{% include [x](_includes/select/view.md) %}
+
+{% include [x](_includes/select/temporary_table.md) %}
+
+{% include [x](_includes/select/from_as_table.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/select_stream.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/select_stream.md
new file mode 100644
index 00000000000..40dd9100bac
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/select_stream.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/select_stream.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/subquery.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/subquery.md
new file mode 100644
index 00000000000..75c6ac92a80
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/subquery.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/subquery.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/toc_i.yaml b/ydb/docs/ru/core/yql/reference/yql-core/syntax/toc_i.yaml
new file mode 100644
index 00000000000..eb3d15839f6
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/toc_i.yaml
@@ -0,0 +1,31 @@
+items:
+- { name: Обзор, href: index.md }
+- { name: Лексическая структура, href: lexer.md }
+- { name: Выражения, href: expressions.md }
+- { name: ACTION, href: action.md }
+- { name: ALTER TABLE, href: alter_table.md, when: feature_map_tables }
+- { name: CREATE TABLE, href: create_table.md }
+- { name: DECLARE, href: declare.md }
+- { name: DELETE, href: delete.md, when: feature_map_tables }
+- { name: DISCARD, href: discard.md }
+- { name: DROP TABLE, href: drop_table.md }
+- { name: GROUP BY, href: group_by.md }
+- { name: EXPORT и IMPORT, href: export_import.md, when: feature_mapreduce }
+- { name: FLATTEN, href: flatten.md }
+- { name: INSERT, href: insert_into.md }
+- { name: INTO RESULT, href: into_result.md }
+- { name: JOIN, href: join.md, when: feature_join }
+- { name: PRAGMA, href: pragma.md }
+- { name: PROCESS STREAM, href: process.md, when: feature_mapreduce and process_command == "PROCESS STREAM" }
+- { name: PROCESS, href: process.md, when: feature_mapreduce and process_command == "PROCESS" }
+- { name: REDUCE, href: reduce.md, when: feature_mapreduce and reduce_command == "REDUCE" }
+- { name: REPLACE, href: replace_into.md, when: feature_replace }
+- { name: SELECT, href: select.md }
+- { name: SELECT STREAM, href: select_stream.md, when: feature_mapreduce and process_command == "PROCESS STREAM" }
+- { name: SUBQUERY, href: subquery.md, when: feature_subquery }
+- { name: UPDATE, href: update.md, when: feature_map_tables }
+- { name: UPSERT, href: upsert_into.md, when: feature_upsert }
+- { name: USE, href: use.md, when: feature_mapreduce }
+- { name: VALUES, href: values.md }
+- { name: WINDOW, href: window.md, when: feature_window_functions }
+- { name: Неподдерживаемые конструкции, href: not_yet_supported.md }
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/update.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/update.md
new file mode 100644
index 00000000000..6b2cb43b7bb
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/update.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/update.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/upsert_into.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/upsert_into.md
new file mode 100644
index 00000000000..7ca3636a735
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/upsert_into.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/upsert_into.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/use.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/use.md
new file mode 100644
index 00000000000..c567fc6b949
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/use.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/use.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/values.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/values.md
new file mode 100644
index 00000000000..e64464f7323
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/values.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/values.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/syntax/window.md b/ydb/docs/ru/core/yql/reference/yql-core/syntax/window.md
new file mode 100644
index 00000000000..3eb79a7b960
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/syntax/window.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/window.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/toc_m.yaml b/ydb/docs/ru/core/yql/reference/yql-core/toc_m.yaml
new file mode 100644
index 00000000000..35ad87ba4d8
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/toc_m.yaml
@@ -0,0 +1,2 @@
+items:
+- include: { mode: merge, path: yql-product/toc_product.yaml }
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/toc_product.yaml b/ydb/docs/ru/core/yql/reference/yql-core/toc_product.yaml
new file mode 100644
index 00000000000..8ed779c15e6
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/toc_product.yaml
@@ -0,0 +1,9 @@
+title: YQL over {{ backend_name }}
+# href: index.md
+items:
+- name: Типы данных
+ include: { mode: link, path: types/toc_i.yaml }
+- name: Синтаксис
+ include: { mode: link, path: syntax/toc_i.yaml }
+- name: Встроенные функции
+ include: { mode: link, path: builtins/toc_i.yaml }
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/cast.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/cast.md
new file mode 100644
index 00000000000..ee71465695a
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/cast.md
@@ -0,0 +1,63 @@
+# Правила преобразования типов через оператор [CAST](../../syntax/expressions.md#cast)
+
+## Правила преобразования примитивных типов данных.
+
+* В процессе преобразования примитивных типов данных часть исходной информации может быть отброшена, если она не содержится в целевом типе. Например:
+ * Дробная часть `Float`/`Double` при преобразовании в целочисленные типы;
+ * Время `Datetime`/`Timestamp` при преобразовании в `Date`.
+ * Таймзона при преобразовании из типов с таймзоной к типу даты/времени без таймзоны.
+* Если для определённого сочетания исходного и целевого типа преобразование не может быть выполнено для всех возможных значений исходного типа, то при неудачном преобразовании `CAST` вернёт `NULL`. В таких случаях к типу возвращаемого значения добавляется один уровень `Optional`, если его не было. Например, конструкции: `CAST("3.14" AS Float?)` и `CAST("3.14" AS Float)` полностью эквиваленты и возвращают `Float?`.
+* Если же преобразование возможно для всех значений исходного типа, то добавление '?' работает как `Just` сверху: `CAST(3.14 AS Utf8?)` то же, что и `Just(CAST(3.14 AS Utf8))`
+Все сочетания примитивных типов, для которых возможен `CAST` описаны [тут](../primitive.md).
+
+
+## Правила преобразований для контейнеров.
+
+### Правила для Optional
+* Если для целевого типа задан больший уровень `Optional` чем для исходного то это эквивалентно добавлению `Just` поверх `CAST` с меньшим уровнем `Optional`.
+* Если же больший уровень `Optional` у исходного типа, то `NULL` на любом уровне больше целевого приводит к `NULL` в результате.
+* При равных уровнях `Optional` значение `NULL` остаётся на том же уровне.
+``` yql
+SELECT
+ CAST(1 AS Int32?), -- тоже что и Just(1)
+ CAST(Just(2/1) AS Float??), -- [2]
+ CAST(Just(3/0) AS Float??) IS NULL; -- false: результат Just(NULL)
+```
+
+### Правила для List/Dict
+* Список формируется путём выполнения `CAST` для каждого элемента исходного списка в тип элемента целевого типа.
+* Если тип элемента целевого типа не опциональный, а `CAST` элемента может быть неуспешным, то такие преобразования отбрасываются. В этом случае список в результате может быть меньшей длины или вовсе пустой, если успешных преобразований не было.
+* Для словарей преобразование выполняется полностью аналогично спискам, выполняя `CAST` для ключей и значений.
+``` yql
+SELECT
+ CAST([-1, 0, 1] AS List<Uint8?>), -- [null, 0, 1]
+ CAST(["3.14", "bad", "42"] AS List<Float>), -- [3.14, 42]
+
+ CAST({-1:3.14, 7:1.6} AS Dict<Uint8, Utf8>), -- {7: "1.6"}
+ CAST({-1:3.14, 7:1.6} AS Dict<Uint8?, Utf8>); -- {7: "1.6", null:"3.14"}
+```
+
+### Правила для Struct/Tuple
+* Структура или кортеж формируется путём выполнения `CAST` для каждого элемента исходного типа в элемент с тем же именем или индексом целевого типа.
+* Если какое-то поле отсутствует в целевом типе, оно просто отбрасывается.
+* Если какое-то поле отсутствует в типе исходного значения, то оно может быть добавлено только если является опциональным, и получает значение `NULL`.
+* Если какое-то поле не является опциональным в целевом типе, но его преобразование может быть неуспешным, то `CAST` добавляет опциональность на уровень структуры или кортежа и может вернуть `NULL` для всего результата.
+``` yql
+SELECT
+ CAST((-1, 0, 1) AS Tuple<Uint16?, Uint16?, Utf8>), -- (null, 0, "1")
+ CAST((-2, 0) AS Tuple<Uint16, Utf8>), -- null
+ CAST((3, 4) AS Tuple<Uint16, String>), -- (3, "4") тип Tuple<Uint16, String>?
+ CAST(("4",) AS Tuple<Uint16, String?>), -- (4, null)
+ CAST((5, 6, null) AS Tuple<Uint8?>); -- (5,) элементы удалены.
+
+SELECT -- Одно поле удалено и одно добавлено: ("three":null, "two": "42")
+ CAST(<|one:"8912", two:42|> AS Struct<two:Utf8, three:Date?>);
+```
+
+### Правила для Variant
+* Для варианта с определёнными именем или индексом выполняется преобразование в вариант с тем же именем или индексом.
+* Если преобразование для варианта может быть неуспешным и тип этого варианта не опциональный, то `CAST` добавляет опциональность на верхний уровень и может вернуть `NULL`.
+* Если какой-то вариант отсутствует в целевом типе, то `CAST` добавляет опциональность на верхний уровень и для такого значения возвращает `NULL`.
+
+### Вложенные контейнеры
+* Все вышеперечисленные правила работают рекурсивно для вложенных контейнеров.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/containers.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/containers.md
new file mode 100644
index 00000000000..807576552b2
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/containers.md
@@ -0,0 +1,23 @@
+# Контейнеры
+
+| Тип | Объявление,</br>пример | Описание |
+| ------------ | ---------------- | ------------- |
+| Список | `List<Type>`,</br>`List<Int32>` | Последовательность переменной длины, состоящая из элементов одного типа.|
+| Словарь | `Dict<KeyType, ValueType>`,</br>`Dict<String,Int32>` | Набор пар ключ—значение с фиксированным типом ключей и значений. |
+| Множество | `Set<KeyType>`,</br>`Set<String>` | Набор элементов с фиксированным типом, является частным случаем словаря с типом значения `Void`. |
+| Кортеж | `Tuple<Type1, ..., TypeN>`,</br>`Tuple<Int32,Double>` | Набор безымянных элементов фиксированной длины с указанными типами всех элементов. |
+| Структура | `Struct<Name1:Type1, ..., NameN:TypeN>`,</br> `Struct<Name:String,Age:Int32>` | Набор именованных полей с указанными типами значений, фиксированный на момент начала запроса (то есть обязательно не зависящий от данных). |
+| Поток | `Stream<Type>`,</br> `Stream<Int32>` | Однопроходной итератор по значениям одного типа. Не является сериализуемым. |
+| Вариант над кортежем | `Variant<Type1, Type2>`,</br> `Variant<Int32,String>` | Кортеж, про который известно, что заполнен ровно один элемент. |
+| Вариант над структурой | `Variant<Name1:Type1, Name2:Type2>`,</br>`Variant<value:Int32,error:String>` | Структура, про которую известно, что заполнен ровно один элемент. |
+| Перечисление | `Enum<Name1, Name2>`,</br>`Enum<value,error>` | Контейнер, в котором выбран ровно один элемент перечисления, который определяется только своим именем. |
+
+При необходимости контейнеры можно вкладывать друг в друга в произвольных комбинациях, например `List<Tuple<Int32,Int32>>`.
+
+[Опциональные значения](../optional.md) в некоторых контекстах также могут рассматриваться как один из видов контейнеров (`Optional<Type>`), который ведёт себя как список длины 0 или 1.
+
+Для создания литералов контейнеров списка, словаря, множества, кортежа, структуры можно использовать [операторную запись](../../builtins/basic.md#containerliteral).
+Для создания литерала варианта над кортежем или структурой используется функция [Variant](../../builtins/basic.md#variant).
+Для создания литерала перечисления используется функция [Enum](../../builtins/basic.md#enum).
+
+Для обращения к элементам контейнера используется [точка или квадратные скобки](../../syntax/expressions.md#items-access), в зависимости от его типа.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_datetime.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_datetime.md
new file mode 100644
index 00000000000..5f904b40ac3
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_datetime.md
@@ -0,0 +1,9 @@
+Тип | Описание | Примечания
+----- | ----- | -----
+`Date` | Дата, точность до дней | Диапазон значений для всех временных типов кроме `Interval` - от нуля часов 01.01.1970 до нуля часов 01.01.2106. Внутреннее представление `Date` – беззнаковое целое 16 бит |
+`Datetime` | Дата/время, точность до секунд | Внутреннее представление – беззнаковое целое 32 бит |
+`Timestamp` | Дата/время, точность до микросекунд | Внутреннее представление – беззнаковое целое 64 бит |
+`Interval` | Интервал времени (знаковый), точность до микросекунд | Диапазон значений – от -136 лет до +136 лет. Внутреннее представление – знаковое целое 64 бит. {% if feature_map_tables %}Не может быть использован в первичном ключе{% endif %}
+`TzDate` | Дата с меткой временной зоны, точность до дней | Не поддерживается в столбцах таблиц
+`TzDateTime` | Дата/время с меткой временной зоны, точность до секунд | Не поддерживается в столбцах таблиц
+`TzTimestamp` | Дата/время с меткой временной зоны, точность до микросекунд | Не поддерживается в столбцах таблиц \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_number.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_number.md
new file mode 100644
index 00000000000..928fe814d7f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_number.md
@@ -0,0 +1,17 @@
+Тип | Описание | Примечания
+----- | ----- | -----
+`Bool` | Логическое значение. |
+`Int8` | Целое число со знаком.<br/>Допустимые значения: от –2<sup>7</sup> до 2<sup>7</sup>–1. | Не поддержан для столбцов таблиц
+`Int16` | Целое число со знаком.<br/>Допустимые значения: от –2<sup>15</sup> до 2<sup>15</sup>–1. | Не поддержан для столбцов таблиц
+`Int32` | Целое число со знаком.<br/>Допустимые значения: от –2<sup>31</sup> до 2<sup>31</sup>–1. |
+`Int64` | Целое число со знаком.<br/>Допустимые значения: от –2<sup>63</sup> до 2<sup>63</sup>–1. |
+`Uint8` | Беззнаковое целое число.<br/>Допустимые значения: от 0 до 2<sup>8</sup>–1. |
+`Uint16` | Беззнаковое целое число.<br/>Допустимые значения: от 0 до 2<sup>16</sup>–1. | Не поддержан для столбцов таблиц
+`Uint32` | Беззнаковое целое число.<br/>Допустимые значения: от 0 до 2<sup>32</sup>–1. |
+`Uint64` | Беззнаковое целое число.<br/>Допустимые значения: от 0 до 2<sup>64</sup>–1. |
+`Float` | Вещественное число с переменной точностью размером 4 байта. | {% if feature_map_tables %}Не может быть использован в первичном ключе{% endif %}
+`Double` | Вещественное число с переменной точностью размером 8 байт. | {% if feature_map_tables %}Не может быть использован в первичном ключе{% endif %}
+`Decimal` | Вещественное число с указанной точностью, до 35 десятичных знаков | {% if feature_map_tables %}При использовании в колонках таблиц точность фиксирована: Decimal (22,9).</br>Не может быть использован в первичном ключе{% endif %}
+{% if feature_map_tables %}
+`DyNumber` | Бинарное представление вещественного числа точностью до 38 знаков.<br/>Допустимые значения: положительные от 1×10<sup>-130</sup> до 1×10<sup>126</sup>–1, отрицательные от -1×10<sup>126</sup>–1 до -1×10<sup>-130</sup> и 0.<br/>Совместим с типом `Number` AWS DynamoDB. Не рекомендуется для использования в {{ backend_name_lower }}-native приложениях. |
+{% endif %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md
new file mode 100644
index 00000000000..f37c2f63186
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/datatypes_primitive_string.md
@@ -0,0 +1,26 @@
+Тип | Описание | Примечания
+----- | ----- | -----
+`String` | Строка, может содержать произвольные бинарные данные |
+`Utf8` | Текст в кодировке [UTF-8](https://en.wikipedia.org/wiki/UTF-8) |
+`Json` | [JSON](https://en.wikipedia.org/wiki/JSON) в текстовом представлении|Не поддерживает возможность сравнения{% if feature_map_tables %}, не может быть использован в первичном ключе{% endif %}
+`JsonDocument` | [JSON](https://en.wikipedia.org/wiki/JSON) в бинарном индексированном представлении | Не поддерживает возможность сравнения{% if feature_map_tables %}, не может быть использован в первичном ключе{% endif %}
+`Yson` | [YSON](https://yt.yandex-team.ru/docs/description/common/yson.html) в текстовом или бинарном представлении | Не поддерживает возможность сравнения{% if feature_map_tables %}, не может быть использован в первичном ключе{% endif %}
+`Uuid` | Универсальный идентификатор [UUID](https://tools.ietf.org/html/rfc4122) | Не поддержан для столбцов таблиц
+
+{% note info "Ограничения на размер" %}
+
+Максимальный размер значения в ячейке {% if feature_map_tables %} неключевого столбца {% endif %} с любым строковым типом данных — 8 МБ.
+
+{% endnote %}
+
+В отличие от типа данных `Json`, который хранит исходное текстовое представление, переданное пользователем, `JsonDocument` использует бинарное индексированное представление. Важное отличие с точки зрения семантики состоит в том, что `JsonDocument` не сохраняет форматирование, порядок ключей в объектах и их дубликаты.
+
+За счет индексированного представления `JsonDocument` позволяет обходить документную модель с использованием `JsonPath` без необходимости парсинга всего содержимого. Это позволяет эффективно выполнять операции из [JSON API](../../builtins/json.md), уменьшая задержки и стоимость пользовательских запросов. Выполнение запросов над `JsonDocument` может быть до нескольких раз эффективнее в зависимости от типа нагрузки.
+
+Из-за добавленной избыточности `JsonDocument` менее эффективен в хранении. Дополнительные накладные расходы на хранение зависят от конкретного содержимого и в среднем составляют 20–30% от исходного объема. Сохранение данных в формате `JsonDocument` требует дополнительной конвертации из текстового представления, что делает его запись менее эффективной. Тем не менее, для большинства read-intensive сценариев, подразумевающих обработку данных из JSON, этот тип данных является предпочтительным и рекомендуется к использованию.
+
+{% note warning %}
+
+Для хранения чисел (JSON Number) в `JsonDocument`, а также для арифметических операций над ними в [JSON API](../../builtins/json.md) используется тип [Double](https://en.wikipedia.org/wiki/Double-precision_floating-point_format). Возможна потеря точности при использовании нестандартных представлений чисел в исходном JSON-документе.
+
+{% endnote %} \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/json.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/json.md
new file mode 100644
index 00000000000..af7bc105f1f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/json.md
@@ -0,0 +1,173 @@
+# Представление данных в формате JSON
+
+## Bool {#bool}
+
+Логическое значение.
+
+* Тип в JSON — `bool`.
+* Пример значения {{ backend_name }} — `true`.
+* Пример значения JSON — `true`.
+
+## Int8, Int16, Int32, Int64 {#int}
+
+Целочисленные знаковые типы.
+
+* Тип в JSON — `number`.
+* Пример значения {{ backend_name }} — `123456`, `-123456`.
+* Пример значения JSON — `123456`, `-123456`.
+
+## Uint8, Uint16, Uint32, Uint64 {#uint}
+
+Целочисленные беззнаковые типы.
+
+* Тип в JSON — `number`.
+* Пример значения {{ backend_name }} — `123456`.
+* Пример значения JSON — `123456`.
+
+## Float {#float}
+
+Вещественное 4-байтное число.
+
+* Тип в JSON — `number`.
+* Пример значения {{ backend_name }} — `0.12345679`.
+* Пример значения JSON — `0.12345679`.
+
+## Double {#double}
+
+Вещественное 8-байтное число.
+
+* Тип в JSON — `number`.
+* Пример значения {{ backend_name }} — `0.12345678901234568`.
+* Пример значения JSON — `0.12345678901234568`.
+
+## Decimal {#decimal}
+
+Число с фиксированной точностью. Поддерживается только Decimal(22, 9).
+
+* Тип в JSON — `string`.
+* Пример значения {{ backend_name }} — `-320.789`.
+* Пример значения JSON — `"-320.789"`.
+
+## String{% if audience != "external" %}, Yson{% endif %} {#string}
+
+Бинарные строки. Алгоритм кодирования в зависимости от значения байта:
+
+* [0-31] — `\u00XX` (6 символов, обозначающих код символа юникода);
+* [32-126] — as is. Это читаемые однобайтовые символы, не требующие эскейпинга;
+* [127-255] — `\u00XX`.
+
+При декодировании происходит обратный процесс. Коды символов в `\u00XX` более 255 не допускаются.
+
+* Тип в JSON — `string`.
+* Пример значения {{ backend_name }} — последовательность из 4 байт:
+ * 5 `0x05` - управляющий символ;
+ * 10 `0x0a` - перенос строки `\n`;
+ * 107 `0x6b` - символ `k`;
+ * 255 `0xff` - символ юникода `ÿ`.
+* Пример значения JSON — `"\u0005\nk\u00FF"`.
+
+## Utf8, Json, Uuid {#utf}
+
+Строковые типы в utf-8. Такие строки представляются в JSON строками с escaping'ом JSON-символов: `\\`, `\"`, `\n`, `\r`, `\t`, `\f`.
+
+* Тип в JSON — `string`.
+* Пример значения {{ backend_name }} — код на С++:
+
+ ```c++
+ "Escaped characters: "
+ "\\ \" \f \b \t \r\n"
+ "Non-escaped characters: "
+ "/ ' < > & []() ".
+ ```
+
+* Пример значения JSON — `"Escaped characters: \\ \" \f \b \t \r\nNon-escaped characters: / ' < > & []() "`.
+
+## Date {#date}
+
+Дата. Uint64, количество дней unix time.
+
+* Тип в JSON — `string`.
+* Пример значения {{ backend_name }} — `18367`.
+* Пример значения JSON — `"2020-04-15"`.
+
+## Datetime {#datetime}
+
+Дата и время. Uint64, количество секунд unix time.
+
+* Тип в JSON — `string`.
+* Пример значения {{ backend_name }} — `1586966302`.
+* Пример значения JSON — `"2020-04-15T15:58:22Z"`.
+
+## Timestamp {#timestamp}
+
+Дата и время. Uint64, количество микросекунд unix time.
+
+* Тип в JSON — `string`.
+* Пример значения {{ backend_name }} — `1586966302504185`.
+* Пример значения JSON — `"2020-04-15T15:58:22.504185Z"`.
+
+## Interval {#interval}
+
+Временной интервал. Int64, точность до микросекунд, допустимы значения интервалов - не более 24 часов.
+
+* Тип в JSON — `number`.
+* Пример значения {{ backend_name }} — `123456`, `-123456`.
+* Пример значения JSON — `123456`, `-123456`.
+
+## Optional {#optional}
+
+Означает, что значение может быть `null`. Если значение `null`, то в JSON также будет `null`. Если значение не `null`, то в JSON значение запишется так же, как если бы тип был не `Optional`.
+
+* Тип в JSON — отсутствует.
+* Пример значения {{ backend_name }} — `null`.
+* Пример значения JSON — `null`.
+
+## List {#list}
+
+Список. Упорядоченный набор значений заданного типа.
+
+* Тип в JSON — `array`.
+* Пример значения {{ backend_name }}:
+ * тип — `List<Int32>`;
+ * значение — `1, 10, 100`.
+* Пример значения JSON — `[1,10,100]`.
+
+## Stream {#stream}
+
+Поток. Однопроходной итератор по значениям одного типа.
+
+* Тип в JSON — `array`.
+* Пример значения {{ backend_name }}:
+ * тип — `Stream<Int32>`;
+ * значение — `1, 10, 100`.
+* Пример значения JSON — `[1,10,100]`.
+
+## Struct {#struct}
+
+Структура. Неупорядоченный набор значений с заданными именами и типом.
+
+* Тип в JSON — `object`.
+* Пример значения {{ backend_name }}:
+ * тип — `Struct<'Id':Uint32,'Name':String,'Value':Int32,'Description':Utf8?>`;
+ * значение — `"Id":1,"Name":"Anna","Value":-100,"Description":null`.
+* Пример значения JSON — `{"Id":1,"Name":"Anna","Value":-100,"Description":null}`.
+
+## Tuple {#tuple}
+
+Кортеж. Упорядоченный набор значений заданных типов.
+
+* Тип в JSON — `array`.
+* Пример значения {{ backend_name }}:
+ * тип — `Tuple<Int32??,Int64???,String??,Utf8???>`;
+ * значение — `10,-1,null,"Some string"`.
+* Пример значения JSON — `[10,-1,null,"Some string"]`.
+
+## Dict {#dict}
+
+Словарь. Неупорядоченный набор пар ключ-значение. И для ключа, и для значения задан тип. В json записывается в массив массивов, состоящих из двух элементов.
+
+* Тип в JSON — `array`.
+* Пример значения {{ backend_name }}:
+ * тип — `Dict<Int64,String>`;
+ * значение — `1:"Value1",2:"Value2"`.
+* Пример значения JSON — `[[1,"Value1"],[2,"Value2"]]`.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/optional.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/optional.md
new file mode 100644
index 00000000000..4f43b0feb1d
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/optional.md
@@ -0,0 +1,49 @@
+## Типы данных, допускающие значение NULL
+
+Любые типизированные данные в YQL, включая столбцы таблиц, бывают как гарантированно имеющие значение, так и потенциально пустые (что обозначается как `NULL`). Типы данных, которые могут содержать значения `NULL`, называются _опциональными_ или, в терминах SQL, — _nullable_.
+
+Опциональные типы данных в [текстовом виде](../type_string.md) обозначаются вопросительным знаком в конце (например, `String?`) или как `Optional<...>`.
+Наиболее часто на опциональных типах данных выполняются следующие операции:
+
+* [IS NULL](../../syntax/expressions.md#is-null) - проверка на пустое значение
+* [COALESCE](../../builtins/basic.md#coalesce) - оставить заполненные значения без изменений, а `NULL` заменить на указанное следом значение по умолчанию
+* [UNWRAP](../../builtins/basic.md#optional-ops) - ивлечь значение оригинального типа из опционального, `T?` преобразуется в `T`
+* [JUST](../../builtins/basic#optional-ops) — изменить тип данных на опциональный текущего, `T` преобразуется в `T?`
+* [NOTHING](../../builtins/basic.md#optional-ops) — создать пустое значение с указанным типом.
+
+`Optional` (nullable) является не свойством типа данных или колонки, а одним из видов [контейнеров](../containers.md), которые могут быть произвольным образом вложены друг в друга. Так, например, столбец с типом `Optional<Optional<Boolean>>` может принимать 4 значения - `NULL` всего контейнера, `NULL` внутреннего контейнера, `TRUE` и `FALSE`. Описанный тип отличается от `List<List<Boolean>>` тем, что роль пустого списка в нем играет `NULL` и отсутствует возможность положить больше одного содержательного элемента. Также `Optional<Optional<T>>` может использоваться в качестве [lookup](/docs/s_expressions/functions#lookup) по ключу в словаре (`Dict(k,v)`) с `Optional<T>` значениями. Такой тип данных результата позволяет отличать лежащий в словаре `NULL` от отсутствия ключа.
+
+**Пример**
+
+```sql
+$dict = {"a":1, "b":null};
+$found = $dict["b"];
+select if($found is not null, unwrap($found), -1);
+```
+
+Результат:
+
+```text
+# column0
+0 null
+```
+
+## Логические и арифметические операции с NULL {#null_expr}
+
+Литерал `NULL` имеет отдельный сингулярный тип `Null` и может быть неявно сконвертирован к любому опциональному типу (в том числе и вложенному `Optional<Optional<...Optional<T>...>>`). В ANSI SQL `NULL` имеет семантику "неизвестное значение" – поэтому логические и арифметические операции с `NULL` или с незаполненными `Optional` имеют некоторые особенности.
+
+**Примеры**
+```
+SELECT
+ True OR NULL, -- Just(True) (работает как True OR <неизвестное значение типа Bool>)
+ False AND NULL, -- Just(False)
+ True AND NULL, -- NULL (точнее Nothing<Bool?> – <неизвестное значение типа Bool>)
+ NULL OR NOT NULL, -- NULL (все NULL-ы "разные")
+ 1 + NULL, -- NULL (Nothing<Int32?>) - результат сложения 1 с
+ -- неизвестным значением типа Int)
+ 1 == NULL, -- NULL (результат сравнения 1 с неизвестным значением типа Int)
+ (1, NULL) == (1, 2), -- NULL (сравнение композитных элементов производится покомпонентно
+ -- через `AND`)
+ (2, NULL) == (1, 3), -- Just(False) (выражение эквивалентно 2 == 1 AND NULL == 3)
+
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/primitive.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/primitive.md
new file mode 100644
index 00000000000..0af21dfa4b8
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/primitive.md
@@ -0,0 +1,120 @@
+# Примитивные типы данных
+
+Термины «простые», «примитивные» и «элементарные» типы данных используются как синонимы.
+
+## Числовые типы {#numeric}
+
+{% include [datatypes](datatypes_primitive_number.md) %}
+
+## Строковые типы {#string}
+
+{% include [datatypes](datatypes_primitive_string.md) %}
+
+## Дата и время {#datetime}
+
+{% include [datatypes](datatypes_primitive_datetime.md) %}
+
+{% include [x](tz_date_types.md) %}
+
+# Приведение простых типов данных {#cast}
+
+## Явное приведение {#explicit-cast}
+
+Явное приведение при помощи [CAST](../../syntax/expressions.md#cast):
+
+### Приведение к численным типам
+
+
+Тип | Bool | Int | Uint | Float | Double | Decimal
+--- | --- | --- | --- | --- | --- | ---
+**Bool** | — | Да<sup>1</sup> | Да<sup>1</sup> | Да<sup>1</sup> | Да<sup>1</sup> | Нет | Да | Нет
+**Int** | Да<sup>2</sup> | — | Да<sup>3</sup> | Да | Да | Да
+**Uint** | Да<sup>2</sup> | Да | — | Да | Да | Да
+**Float** | Да<sup>2</sup> | Да | Да | — | Да | Нет
+**Double** | Да<sup>2</sup> | Да | Да | Да | — | Нет
+**Decimal** | Нет | Да | Да | Да | Да | —
+**String** | Да | Да | Да | Да | Да | Да
+**Utf8** | Да | Да | Да | Да | Да | Да
+**Json** | Нет | Нет | Нет | Нет | Нет | Нет
+**Yson** | Да<sup>4</sup> | Да<sup>4</sup> | Да<sup>4</sup> | Да<sup>4</sup> | Да<sup>4</sup> | Да<sup>4</sup>
+**Uuid** | Нет | Нет | Нет | Нет | Нет | Нет
+**Date** | Нет | Да | Да | Да | Да | Нет | Да
+**Datetime** | Нет | Да | Да | Да | Да | Нет
+**Timestamp** | Нет | Да | Да | Да | Да | Нет
+**Interval** | Нет | Да | Да | Да | Да | Нет
+
+<sup>1</sup> `True` преобразуется в `1`, `False` преобразуется в `0`.
+<sup>2</sup> Любое значение кроме `0` преобразуется в `True`, `0` преобразуется в `False`.
+<sup>3</sup> Возможно только в случае неотрицательного значения.
+<sup>4</sup> При помощи встроенной функции [Yson::ConvertTo](../../udf/list/yson.md#ysonconvertto).
+
+### Приведение к типам данных даты и времени
+
+Тип | Date | Datetime | Timestamp | Interval
+--- | --- | --- | --- | ---
+**Bool** | Нет | Нет | Нет | Нет
+**Int** | Да | Да | Да | Да
+**Uint** | Да | Да | Да | Да
+**Float** | Нет | Нет | Нет | Нет
+**Double** | Нет | Нет | Нет | Нет
+**Decimal** | Нет | Нет | Нет | Нет
+**String** | Да | Да | Да | Да
+**Utf8** | Да | Да | Да | Да
+**Json** | Нет | Нет | Нет | Нет
+**Yson** | Нет | Нет | Нет | Нет
+**Uuid** | Нет | Нет | Нет | Нет
+**Date** | — | Да | Да | Нет
+**Datetime** | Да | — | Да | Нет
+**Timestamp** | Да | Да | — | Нет
+**Interval** | Нет | Нет | Нет | — | —
+
+### Приведение к другим типам данных
+
+Тип | String | Utf8 | Json | Yson | Uuid
+--- | --- | --- | --- | --- | ---
+**Bool** | Да | Нет | Нет | Нет | Нет |
+**Int** | Да | Нет | Нет | Нет | Нет
+**Uint** | Да | Нет | Нет | Нет | Нет
+**Float** | Да | Нет | Нет | Нет | Нет
+**Double** | Да | Нет | Нет | Нет | Нет
+**Decimal** | Да | Нет | Нет | Нет | Нет
+**String** | — | Да | Да | Да | Да
+**Utf8** | Да | — | Нет | Нет | Нет
+**Json** | Да | Да | — | Нет | Нет
+**Yson** | Да<sup>4</sup> | Нет | Нет | Нет | Нет
+**Uuid** | Да | Да | Нет | Нет | —
+**Date** | Да | Да | Нет | Нет | Нет
+**Datetime** | Да | Да | Нет | Нет | Нет
+**Timestamp** | Да | Да | Нет | Нет | Нет
+**Interval** | Да | Да | Нет | Нет | Нет
+
+<sup>4</sup> При помощи встроенной функции [Yson::ConvertTo](../../udf/list/yson.md#ysonconvertto).
+
+**Примеры**
+
+{% include [x](../../_includes/cast_examples.md) %}
+
+## Неявное приведение {#implicit-cast}
+
+Неявное приведение типов, которое возникает в базовых операциях (+-\*/) между разными типами данных. В ячейках таблицы указан тип результата операции, если она возможна:
+
+### Численные типы
+
+Тип | Int | Uint | Float | Double
+--- | --- | --- | --- | ---
+**Int** | — | `Int` | `Float` | `Double`
+**Uint** | `Int` | — | `Float` | `Double`
+**Float** | `Float` | `Float` | — | `Double`
+**Double** | `Double` | `Double` | `Double` | —
+
+### Типы даты и времени
+
+Тип | Date | Datetime | Timestamp | Interval | TzDate | TzDatetime | TzTimestamp
+--- | --- | --- | --- | --- | --- | --- | ---
+**Date** | — | — | — | `Date` | — | — | —
+**Datetime** | — | — | — | `Datetime` | — | — | —
+**Timestamp** | — | — | — | `Timestamp` | — | — | —
+**Interval** | `Date` | `Datetime` | `Timestamp` | — | `TzDate` | `TzDatetime` | `TzTimestamp`
+**TzDate** | — | — | — | `TzDate` | — | — | —
+**TzDatetime** | — | — | — | `TzDatetime` | — | — | —
+**TzTimestamp** | — | — | — | `TzTimestamp` | — | — | —
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/special.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/special.md
new file mode 100644
index 00000000000..33393b3dca9
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/special.md
@@ -0,0 +1,14 @@
+# Специальные типы данных
+
+Тип | Описание
+----- | -----
+`Callable` | Вызываемое значение, которое можно исполнить, передав аргументы в круглых скобках в SQL-синтаксисе YQL{% if feature_mapreduce %}, либо с помощью функции `Apply` при использовании [s-expressions](/docs/s_expressions) синтаксиса{% endif %}.
+`Resource` | Непрозрачный указатель на ресурс, который можно передавать между пользовательскими функциями (UDF, user defined function). Тип возвращаемого и принимаемого ресурса объявляется внутри функции строковой меткой. При передаче ресурса YQL проверяет совпадение меток, чтобы предотвратить передачу ресурсов между несовместимыми функциями. В случае несовпадения меток происходит ошибка типизации.
+`Tagged` | Возможность дать прикладное имя какому-либо другому типу.
+`Generic` | Тип данных у типа данных.
+`Unit` | Тип данных у невычисляемых сущностей (источники и приемники данных, атомы и т.&nbsp;п.).
+`Null` | Сингулярный тип данных с единственным возможным значением null. Является типом литерала `NULL` и может преобразовываться к любому `Optional` типу.
+`Void` | Сингулярный тип данных с единственным возможным значением `null`.
+`EmptyList` | сингулярный тип данных с единственным возможным значением []; является типом литерала `[]` и может преобразовываться к любому `List` типу.
+`EmptyDict` | сингулярный тип данных с единственным возможным значением {}; является типом литерала `{}` и может преобразовываться к любому `Dict` или `Set` типу.
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/type_string.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/type_string.md
new file mode 100644
index 00000000000..c08dc6772e0
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/type_string.md
@@ -0,0 +1,73 @@
+# Работа с текстовым представлением типов данных
+
+## Введение {#intro}
+
+Так как YQL является строго типизированным языком, во многих аспектах работы с ним тип данных имеет большое значение. Для удобства работы с типами существует конвенция описания типов данных YQL в текстовом виде. Она используется в разных местах документации, а также существует библиотека, предоставляющая функции для построения типа данных по текстовому описанию (например, при ручном описании сигнатуры вызываемого значения) или для сериализации типа данных в строку для отладки.
+
+Функции для работы с типами данных [описаны в статье](../../builtins/types.md), а ниже описан сам формат текстового представления типов данных.
+
+## Общие правила {#rules}
+
+* [Примитивные типы данных](../primitive.md) представляются в текстовом виде просто своим именем.
+
+* Сложный тип данных представляет собой композицию из других типов данных. Если представить эту композицию в виде дерева, то на листьях окажутся [примитивные типы данных](../primitive.md), а в остальных узлах — [контейнеры](../containers.md). [Специальные типы данных](../special.md) можно рассматривать как исключение, они могут находиться и там и там.
+
+* Текстовое представление повторяет структуру этого дерева в порядке от корня к листьям: в каждом узле дерева указывается имя текущего типа данных, а переход на уровень глубже обозначается различными видами скобок.
+
+* Допустимо использование пробелов и переносов строк, если это облегчает чтение.
+
+* Если идентификатор состоит не только из английских букв и цифр, то его нужно записывать в одиночных кавычках и использовать C-escaping.
+
+## Контейнеры {#containers}
+
+* Для указания типов элементов контейнера используются угловые скобки.
+
+ Пример: `List<Int32>`.
+
+* Если контейнер предполагает несколько разнородных элементов, то они перечисляются внутри угловых скобок через запятую.
+
+ Пример: `Tuple<Int32, String>`.
+
+* Если контейнер предполагает именованные элементы, то вместо типов данных через запятую используются пары из имени и типа через двоеточие.
+
+ Пример: `Struct<a:Int32, b:String>`.
+
+* Нижележащий тип контейнера `Variant` выбирается в зависимости от наличия имён в аргументах.
+
+ Пример: `Variant<Int32, String>` — вариант над кортежем, `Variant<a:Int32, b:String>` — вариант над структурой.
+
+## Типы, допускающие NULL {#optional}
+
+* В терминах YQL это называется `Optional`, в терминах классического SQL — nullable.
+
+* Формально этот тип является контейнером, т.е. запись `Optional<...>` допустима, но обычно вместо неё используется shortcut в виде суффикса из знака вопроса.
+
+ Пример: `String?`.
+
+## Вызываемые значения {#callable}
+
+* Базовая форма вызываемых значений выглядит следующим образом: `(arg1, arg2, ...) -> result`.
+
+ Пример описания сигнатуры функции, принимающей две строки и возвращающей число: `(String, String) -> Int64`.
+
+* Вызываемые значения могут возвращать вызываемые значения, в этом случае они образуют цепочку необходимой длины.
+
+ Пример: `(String, String) -> (String, String) -> Int64`.
+
+* Опциональные аргументы должны иметь на верхнем уровне тип `Optional` и обрамляются в квадратные скобки.
+
+ Пример: `(String, [String?, Double?]) -> Int64`.
+
+* У аргументов вызываемых значений могут быть указаны флаги.
+
+ На текущий момент возможен только один флаг — `AutoMap`, который означает, что если в этот аргумент передали NULL, то результат нужно сделать тоже NULL, а саму функцию не запускать.
+
+ Пример: `(String{Flags: AutoMap}) -> Int64`.
+
+* Если нужен `Optional<Callable<...>>`, то нужно использовать именно такую форму, т.к. знак вопроса в конце относится к результату вызываемого значения.
+
+## Ресурсы {#resources}
+
+* В отличие от контейнеров, ресурс параметризуется не типом элемента (ресурс является указателем в памяти и YQL ничего не знает о его содержимом), а строковой меткой, которая может использоваться для защиты от передачи ресурсов между несовместимыми функциями.
+
+ Пример: `Resource<Foo>`.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/tz_date_types.md b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/tz_date_types.md
new file mode 100644
index 00000000000..d098f424afd
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/_includes/tz_date_types.md
@@ -0,0 +1,16 @@
+### Особенности поддержки типов с меткой временной зоны
+
+Метка временной зоны у типов `TzDate`, `TzDatetime`, `TzTimestamp` это атрибут, который используется:
+
+* При преобразовании ([CAST](../../syntax/expressions.md#cast), [DateTime::Parse](../../udf/list/datetime.md#parse), [DateTime::Format](../../udf/list/datetime.md#format)) в строку и из строки.
+* В [DateTime::Split](../../udf/list/datetime.md#split) - появляется компонент таймзоны в `Resource<TM>`.
+
+Само значение позиции во времени у этих типов хранится в UTC, и метка таймзоны никак не участвует в прочих расчётах. Например:
+``` yql
+select --эти выражения всегда true для любых таймзон: таймзона не влияет на точку во времени.
+ AddTimezone(CurrentUtcDate(), "Europe/Moscow") ==
+ AddTimezone(CurrentUtcDate(), "America/New_York"),
+ AddTimezone(CurrentUtcDatetime(), "Europe/Moscow") ==
+ AddTimezone(CurrentUtcDatetime(), "America/New_York");
+```
+Важно понимать, что при преобразованиях между `TzDate` и `TzDatetime` или `TzTimestamp` дате соответствует не полночь по локальному времени таймзоны, а полночь по UTC для даты в UTC.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/cast.md b/ydb/docs/ru/core/yql/reference/yql-core/types/cast.md
new file mode 100644
index 00000000000..cacca351321
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/cast.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/cast.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/containers.md b/ydb/docs/ru/core/yql/reference/yql-core/types/containers.md
new file mode 100644
index 00000000000..6d4196bdb95
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/containers.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/containers.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/index.md b/ydb/docs/ru/core/yql/reference/yql-core/types/index.md
new file mode 100644
index 00000000000..08821222c36
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/index.md
@@ -0,0 +1,11 @@
+# Типы данных YQL
+
+В данном разделе размещены статьи по типам данных YQL:
+
+- [Простые/примитивные типы](primitive.md)
+- [Опциональные типы](optional.md)
+- [Контейнеры](containers.md)
+- [Специальные типы](special.md)
+- [Преобразования типов](cast.md)
+- [Текстовое представление типов данных](type_string.md)
+- [Представление данных в формате JSON](json.md) \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/json.md b/ydb/docs/ru/core/yql/reference/yql-core/types/json.md
new file mode 100644
index 00000000000..2a96f5886ec
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/json.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/json.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/optional.md b/ydb/docs/ru/core/yql/reference/yql-core/types/optional.md
new file mode 100644
index 00000000000..a2722f9f6b4
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/optional.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/optional.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/primitive.md b/ydb/docs/ru/core/yql/reference/yql-core/types/primitive.md
new file mode 100644
index 00000000000..121b1095423
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/primitive.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/primitive.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/special.md b/ydb/docs/ru/core/yql/reference/yql-core/types/special.md
new file mode 100644
index 00000000000..bed7bcb5571
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/special.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/special.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/toc_i.yaml b/ydb/docs/ru/core/yql/reference/yql-core/types/toc_i.yaml
new file mode 100644
index 00000000000..e5b55f2535c
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/toc_i.yaml
@@ -0,0 +1,17 @@
+items:
+- name: Обзор
+ href: index.md
+- name: Простые
+ href: primitive.md
+- name: Опциональные
+ href: optional.md
+- name: Контейнеры
+ href: containers.md
+- name: Специальные
+ href: special.md
+- name: Преобразования типов
+ href: cast.md
+- name: Текстовое представление типов данных
+ href: type_string.md
+- name: JSON
+ href: json.md \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/types/type_string.md b/ydb/docs/ru/core/yql/reference/yql-core/types/type_string.md
new file mode 100644
index 00000000000..acbdaff6a48
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/types/type_string.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/type_string.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/histogram.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/histogram.md
new file mode 100644
index 00000000000..99c7640f7fd
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/histogram.md
@@ -0,0 +1,19 @@
+# Histogram
+
+Набор вспомогательных функций для [агрегатной функции HISTOGRAM](../../../builtins/aggregation.md). В описании сигнатур ниже под HistogramStruct подразумевается результат работы агрегатной функции `HISTOGRAM`, `LinearHistogram` или `LogarithmicHistogram`, который является структурой определенного вида.
+
+**Список функций**
+
+* ```Histogram::Print(HistogramStruct{Flags:AutoMap}, Byte?) -> String```
+* ```Histogram::Normalize(HistogramStruct{Flags:AutoMap}, [Double?]) -> HistogramStruct``` - во втором аргументе желаемая площадь гистограммы, по умолчанию 100.
+* ```Histogram::ToCumulativeDistributionFunction(HistogramStruct{Flags:AutoMap}) -> HistogramStruct```
+* ```Histogram::GetSumAboveBound(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+* ```Histogram::GetSumBelowBound(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+* ```Histogram::GetSumInRange(HistogramStruct{Flags:AutoMap}, Double, Double) -> Double```
+* ```Histogram::CalcUpperBound(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+* ```Histogram::CalcLowerBound(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+* ```Histogram::CalcUpperBoundSafe(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+* ```Histogram::CalcLowerBoundSafe(HistogramStruct{Flags:AutoMap}, Double) -> Double```
+
+У `Histogram::Print` есть опциональный числовой аргумент, который задает максимальную длину столбцов гистограммы (в символах, так как гистограмма рисуется в технике ASCII-арт). Значение по умолчанию — 25. Данная функция предназначена в первую очередь для просмотра гистограмм в консоли{% if feature_webui %}. [Веб-интерфейс](../../../interfaces/web.md) автоматически делает их интерактивную визуализацию{% endif %}.
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/index/intro.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/index/intro.md
new file mode 100644
index 00000000000..36fd3117066
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/index/intro.md
@@ -0,0 +1,4 @@
+# Функции встроенных C++ библиотек
+
+Многие прикладные функции, которые с одной стороны слишком специфичны, чтобы стать частью ядра YQL, а с другой — могут быть полезны широкому кругу пользователей, доступны через встроенные C++ библиотеки.
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/index/list.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/index/list.md
new file mode 100644
index 00000000000..cf1261d8fed
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/index/list.md
@@ -0,0 +1,13 @@
+* [Hyperscan](../../hyperscan.md)
+* [Pcre](../../pcre.md)
+* [Pire](../../pire.md)
+* [Re2](../../re2.md)
+* [String](../../string.md)
+* [Unicode](../../unicode.md)
+* [DateTime](../../datetime.md)
+* [Url](../../url.md)
+* [Ip](../../ip.md)
+* [Yson](../../yson.md)
+* [Digest](../../digest.md)
+* [Math](../../math.md)
+* [Histogram](../../histogram.md) \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/string.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/string.md
new file mode 100644
index 00000000000..057d8697b34
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/string.md
@@ -0,0 +1,86 @@
+# String
+Функции для работы с ASCII-строками.
+
+**Список функций**
+
+* ```String::Base64Encode(String{Flags:AutoMap}) -> String```
+* ```String::Base64Decode(String) -> String?```
+* ```String::Base64StrictDecode(String) -> String?```
+* ```String::EscapeC(String{Flags:AutoMap}) -> String```
+* ```String::UnescapeC(String{Flags:AutoMap}) -> String```
+* ```String::HexEncode(String{Flags:AutoMap}) -> String```
+* ```String::HexDecode(String) -> String?```
+* ```String::EncodeHtml(String{Flags:AutoMap}) -> String```
+* ```String::DecodeHtml(String{Flags:AutoMap}) -> String```
+* ```String::CgiEscape(String{Flags:AutoMap}) -> String```
+* ```String::CgiUnescape(String{Flags:AutoMap}) -> String```
+* ```String::Strip(String{Flags:AutoMap}) -> String```
+* ```String::Collapse(String{Flags:AutoMap}) -> String```
+* ```String::CollapseText(String{Flags:AutoMap}, Uint64) -> String```
+* ```String::Contains(String?, String) -> Bool```
+* ```String::Find(String{Flags:AutoMap}, String, [Uint64?]) -> Int64``` - возвращает первую найденную позицию или -1; опциональный аргумент - отступ от начала строки
+* ```String::ReverseFind(String{Flags:AutoMap}, String, [Uint64?]) -> Int64``` - возвращает последнюю найденную позицию или -1; опциональный аргумент - отступ от начала строки
+* ```String::HasPrefix(String?, String) -> Bool```
+* ```String::HasPrefixIgnoreCase(String?, String) -> Bool```
+* ```String::StartsWith(String?, String) -> Bool```
+* ```String::StartsWithIgnoreCase(String?, String) -> Bool```
+* ```String::HasSuffix(String?, String) -> Bool```
+* ```String::HasSuffixIgnoreCase(String?, String) -> Bool```
+* ```String::EndsWith(String?, String) -> Bool```
+* ```String::EndsWithIgnoreCase(String?, String) -> Bool```
+* ```String::Substring(String{Flags:AutoMap}, [Uint64?, Uint64?]) -> String```
+* ```String::AsciiToLower(String{Flags:AutoMap}) -> String``` - меняет только латинские символы. Для работы с другими алфавитами см. Unicode::ToLower
+* ```String::AsciiToUpper(String{Flags:AutoMap}) -> String``` - меняет только латинские символы. Для работы с другими алфавитами см. Unicode::ToUpper
+* ```String::AsciiToTitle(String{Flags:AutoMap}) -> String``` - меняет только латинские символы. Для работы с другими алфавитами см. Unicode::ToTitle
+* ```String::SplitToList( String?, String, [ DelimeterString:Bool?, SkipEmpty:Bool?, Limit:Uint64? ]) -> List<String>```
+ Первый аргумент -- исходная строка
+ Второй аргумент -- разделитель
+ Третий аргумент -- параметры:
+ - DelimeterString:Bool? — считать разделитель строкой (true, по умолчанию) или набором символов "любой из" (false)
+ - SkipEmpty:Bool? - пропускать ли пустые строки в результате, по умолчанию false
+ - Limit:Uint64? - ограничение на число извлекаемых компонент, по умолчанию не ограничено; необработанный суффикс оригинальной строки возвращается последним элементом при превышении лимита
+
+* ```String::JoinFromList(List<String>{Flags:AutoMap}, String) -> String```
+* ```String::ToByteList(List<String>{Flags:AutoMap}) -> List<Byte>```
+* ```String::FromByteList(List<Uint8>) -> String```
+* ```String::ReplaceAll(String{Flags:AutoMap}, String, String) -> String``` - аргументы: input, find, replacement
+* ```String::ReplaceFirst(String{Flags:AutoMap}, String, String) -> String``` - аргументы: input, find, replacement
+* ```String::ReplaceLast(String{Flags:AutoMap}, String, String) -> String``` - аргументы: input, find, replacement
+* ```String::RemoveAll(String{Flags:AutoMap}, String) -> String ``` - неупорядоченный набор символов во втором аргументе, удаляются все вхождения символов из набора
+* ```String::RemoveFirst(String{Flags:AutoMap}, String) -> String ``` - неупорядоченный набор символов во втором аргументе, удаляется только первый встреченный символ из набора
+* ```String::RemoveLast(String{Flags:AutoMap}, String) -> String ``` - неупорядоченный набор символов во втором аргументе, удаляется только последний встреченный символ из набора
+* ```String::IsAscii(String{Flags:AutoMap}) -> Bool```
+* ```String::IsAsciiSpace(String{Flags:AutoMap}) -> Bool```
+* ```String::IsAsciiUpper(String{Flags:AutoMap}) -> Bool```
+* ```String::IsAsciiLower(String{Flags:AutoMap}) -> Bool```
+* ```String::IsAsciiAlpha(String{Flags:AutoMap}) -> Bool```
+* ```String::IsAsciiAlnum(String{Flags:AutoMap}) -> Bool```
+* ```String::IsAsciiHex(String{Flags:AutoMap}) -> Bool```
+* ```String::LevensteinDistance(String{Flags:AutoMap}, String{Flags:AutoMap}) -> Uint64```
+* ```String::LeftPad(String{Flags:AutoMap}, Uint64, [String?]) -> String```
+* ```String::RightPad(String{Flags:AutoMap}, Uint64) -> String```
+* ```String::Hex(Uint64{Flags:AutoMap}) -> String```
+* ```String::SHex(Int64{Flags:AutoMap}) -> String```
+* ```String::Bin(Uint64{Flags:AutoMap}) -> String```
+* ```String::SBin(Int64{Flags:AutoMap}) -> String```
+* ```String::HexText(String{Flags:AutoMap}) -> String```
+* ```String::BinText(String{Flags:AutoMap}) -> String```
+* ```String::HumanReadableDuration(Uint64{Flags:AutoMap}) -> String```
+* ```String::HumanReadableQuantity(Uint64{Flags:AutoMap}) -> String```
+* ```String::HumanReadableBytes(Uint64{Flags:AutoMap}) -> String```
+* ```String::Prec(Double{Flags:AutoMap}, Uint64) -> String* ```
+* ```String::Reverse(String?) -> String?```
+
+{% note alert %}
+
+Функции из библиотеки String не поддерживают кириллицу и умеют работать только с ASCII символами. Для работы со строками в кодировке UTF-8 используйте функции из [Unicode](../unicode.md).
+
+{% endnote %}
+
+**Примеры**
+
+```sql
+SELECT String::Base64Encode("YQL"); -- "WVFM"
+SELECT String::Strip("YQL "); -- "YQL"
+SELECT String::SplitToList("1,2,3,4,5,6,7", ",", 3 as Limit); -- ["1", "2", "3", "4,5,6,7"]
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/unicode.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/unicode.md
new file mode 100644
index 00000000000..6853c0af185
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/unicode.md
@@ -0,0 +1,82 @@
+# Unicode
+Функции для работы с Unicode строками.
+
+**Список функций**
+
+* ```Unicode::IsUtf(String) -> Bool```
+ Проверяет является ли строка валидной utf-8 последовательностью. Например, строка ```"\xF0"``` не является валидной utf-8 последовательностью, а строка ```"\xF0\x9F\x90\xB1"``` корректно описывает utf-8 emoji с котиком.
+
+* ```Unicode::GetLength(Utf8{Flags:AutoMap}) -> Uint64```
+ Возвращает длину utf-8 строки в символах (unicode code points). Суррогатные пары учитываются как один символ.
+* ```Unicode::Find(Utf8{Flags:AutoMap}, Utf8, [Uint64?]) -> Uint64?```
+* ```Unicode::RFind(Utf8{Flags:AutoMap}, Utf8, [Uint64?]) -> Uint64?```
+* ```Unicode::Substring(Utf8{Flags:AutoMap}, from:Uint64?, len:Uint64?) -> Utf8```
+ Возвращает подстроку начиная с символа ```from``` длиной в ```len``` символов. Если аргумент ```len``` опущен, то подстрока берется до конца исходной строки.
+
+* Функции ```Unicode::Normalize...``` приводят переданную utf-8 строку в одну из [нормальных форм](https://unicode.org/reports/tr15/#Norm_Forms):
+
+ * ```Unicode::Normalize(Utf8{Flags:AutoMap}) -> Utf8``` -- NFC
+ * ```Unicode::NormalizeNFD(Utf8{Flags:AutoMap}) -> Utf8```
+ * ```Unicode::NormalizeNFC(Utf8{Flags:AutoMap}) -> Utf8```
+ * ```Unicode::NormalizeNFKD(Utf8{Flags:AutoMap}) -> Utf8```
+ * ```Unicode::NormalizeNFKC(Utf8{Flags:AutoMap}) -> Utf8```
+
+
+* ```Unicode::Translit(Utf8{Flags:AutoMap}, [String?]) -> Utf8```
+ Транслитерирует в латинский алфавит слова переданной строки, целиком состоящие из символов алфавита языка, переданного вторым аргументом. Если язык не указан, то транслитерация ведется с русского. Доступные языки: "kaz", "rus", "tur", "ukr".
+
+* ```Unicode::LevensteinDistance(Utf8{Flags:AutoMap}, Utf8{Flags:AutoMap}) -> Uint64```
+ Вычисляет расстояние Левенштейна для переданных строк.
+
+* ```Unicode::Fold(Utf8{Flags:AutoMap}, [ Language:String?, DoLowerCase:Bool?, DoRenyxa:Bool?, DoSimpleCyr:Bool?, FillOffset:Bool? ]) -> Utf8```
+ Выполняет [case folding](https://www.w3.org/TR/charmod-norm/#definitionCaseFolding) для переданной строки. ```Language``` задается по тем же правилам, что и в ```Unicode::Translit()```; ```DoLowerCase``` приводит строку к нижнему регистру, по умолчанию ```true```.
+
+* ```Unicode::ReplaceAll(Utf8{Flags:AutoMap}, Utf8, Utf8) -> Utf8```
+ Aргументы: ```input```, ```find```, ```replacement```. Заменяет все вхождения строки ```find``` в ```input``` на ```replacement```.
+
+* ```Unicode::ReplaceFirst(Utf8{Flags:AutoMap}, Utf8, Utf8) -> Utf8```
+ Aргументы: ```input```, ```find```, ```replacement```. Заменяет первое вхождение строки ```find``` в ```input``` на ```replacement```.
+
+* ```Unicode::ReplaceLast(Utf8{Flags:AutoMap}, Utf8, Utf8) -> Utf8```
+ Aргументы: ```input```, ```find```, ```replacement```. Заменяет последнее вхождение строки ```find``` в ```input``` на ```replacement```.
+
+* ```Unicode::RemoveAll(Utf8{Flags:AutoMap}, Utf8) -> Utf8```
+ Второй аргумент интерпретируется как неупорядоченный набор символов для удаления. Удаляются все вхождения символов из набора.
+
+* ```Unicode::RemoveFirst(Utf8{Flags:AutoMap}, Utf8) -> Utf8```
+ Второй аргумент интерпретируется как неупорядоченный набор символов для удаления. Удаляется только первое вхождение символа из набора.
+
+* ```Unicode::RemoveLast(Utf8{Flags:AutoMap}, Utf8) -> Utf8```
+ Второй аргумент интерпретируется как неупорядоченный набор символов для удаления. Удаляется только последнее вхождение символа из набора.
+
+* ```Unicode::ToCodePointList(Utf8{Flags:AutoMap}) -> List<Uint32>```
+* ```Unicode::FromCodePointList(List<Uint32>{Flags:AutoMap}) -> Utf8```
+* ```Unicode::Reverse(Utf8{Flags:AutoMap}) -> Utf8```
+* ```Unicode::ToLower(Utf8{Flags:AutoMap}) -> Utf8```
+* ```Unicode::ToUpper(Utf8{Flags:AutoMap}) -> Utf8```
+* ```Unicode::ToTitle(Utf8{Flags:AutoMap}) -> Utf8```
+* ```Unicode::SplitToList( Utf8?, Utf8, [ DelimeterString:Bool?, SkipEmpty:Bool?, Limit:Uint64? ]) -> List<Utf8>```
+ Первый аргумент -- исходная строка
+ Второй аргумент -- разделитель
+ Третий аргумент -- параметры:
+ - DelimeterString:Bool? — считать разделитель строкой (true, по умолчанию) или набором символов "любой из" (false)
+ - SkipEmpty:Bool? - пропускать ли пустые строки в результате, по умолчанию false
+ - Limit:Uint64? - ограничение на число извлекаемых компонент, по умолчанию не ограничено; необработанный суффикс оригинальной строки возвращается последним элементом при превышении лимита
+
+* ```Unicode::JoinFromList(List<Utf8>{Flags:AutoMap}, Utf8) -> Utf8```
+
+* ```Unicode::ToUint64(Utf8{Flags:AutoMap}, [Uint16?]) -> Uint64```
+ Второй опциональный аргумент задает систему счисления, по умолчанию 0 - автоматическое определение по префиксу.
+ Поддерживаемые префиксы : 0x(0X) - base-16, 0 - base-8. Система по-умолчанию - base-10.
+ Знак '-' перед числом интерпретируется как в беззнаковой арифметике языка C, например -0x1 -> UI64_MAX.
+ В случае наличия в строке некорректных символов или выхода числа за границы ui64 функция завершается с ошибкой.
+* ```Unicode::TryToUint64(Utf8{Flags:AutoMap}, [Uint16?]) -> Uint64?```
+ Аналогично функции Unicode::ToUint64(), но вместо ошибки возвращает Nothing.
+
+
+**Примеры**
+
+```sql
+SELECT Unicode::Fold("Eylül", "Turkish" AS Language); -- "eylul"
+SELECT Unicode::GetLength("жніўня"); -- 6
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/url.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/url.md
new file mode 100644
index 00000000000..bc5d10921d4
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/url.md
@@ -0,0 +1,193 @@
+# Url
+
+## Normalize {#normalize}
+
+* ```Url::Normalize(String) -> String?```
+
+Нормализует URL удобным для Web-роботов образом: приводит hostname в нижний регистр, выкидывает фрагмент и т.п.
+Результат нормализации зависит только от самого URL. В процессе нормализации **НЕ** выполняются операции, зависящие от внешних данных: приведение по дублям, зеркалам и т.п.
+
+Возвращаемое значение:
+* нормализованный URL;
+* `NULL`, если переданный строковый аргумент не удалось распарсить как URL.
+
+**Примеры**
+
+```sql
+SELECT Url::Normalize("hTTp://wWw.yAnDeX.RU/"); -- "http://www.yandex.ru/"
+SELECT Url::Normalize("http://ya.ru#foo"); -- "http://ya.ru/"
+```
+
+## NormalizeWithDefaultHttpScheme {#normalizewithdefaulthttpscheme}
+
+* ```Url::NormalizeWithDefaultHttpScheme(String?) -> String?```
+
+Выполняет нормализацию аналогично `Url::Normalize`, но подставляет схему `http://` в случае, если схемы нет.
+
+Возвращаемое значение:
+
+* нормализованный URL;
+* исходный URL, если нормализация не удалась.
+
+**Примеры**
+
+```sql
+SELECT Url::NormalizeWithDefaultHttpScheme("wWw.yAnDeX.RU"); -- "http://www.yandex.ru/"
+SELECT Url::NormalizeWithDefaultHttpScheme("http://ya.ru#foo"); -- "http://ya.ru/"
+```
+
+## Encode / Decode {#encode}
+
+Кодируют UTF-8 строку в urlencoded формат (`Url::Encode`) и обратно (`Url::Decode`).
+
+**Список функций**
+
+* ```Url::Encode(String?) -> String?```
+* ```Url::Decode(String?) -> String?```
+
+**Примеры**
+
+```sql
+SELECT Url::Decode("http://ya.ru/%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0");
+ -- "http://ya.ru/страница"
+SELECT Url::Encode("http://ya.ru/страница");
+ -- "http://ya.ru/%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B8%D1%86%D0%B0"
+```
+
+## Parse {#parse}
+
+Разбирает URL на составные части.
+
+* ```Url::Parse(Parse{Flags:AutoMap}) -> Struct< Frag: String?, Host: String?, ParseError: String?, Pass: String?, Path: String?, Port: String?, Query: String?, Scheme: String?, User: String? >```
+
+**Примеры**
+
+```sql
+SELECT Url::Parse(
+ "https://en.wikipedia.org/wiki/Isambard_Kingdom_Brunel?s=24&g=h-24#Great_Western_Railway");
+/*
+(
+ "Frag": "Great_Western_Railway",
+ "Host": "en.wikipedia.org",
+ "ParseError": null,
+ "Pass": null,
+ "Path": "/wiki/Isambard_Kingdom_Brunel",
+ "Port": null,
+ "Query": "s=24&g=h-24",
+ "Scheme": "https",
+ "User": null
+)
+*/
+```
+
+## Get... {#get}
+
+Получение компонента URL.
+
+**Список функций**
+
+* ```Url::GetScheme(String{Flags:AutoMap}) -> String```
+* ```Url::GetHost(String?) -> String?```
+* ```Url::GetHostPort(String?) -> String?```
+* ```Url::GetSchemeHost(String?) -> String?```
+* ```Url::GetSchemeHostPort(String?) -> String?```
+* ```Url::GetPort(String?) -> String?```
+* ```Url::GetTail(String?) -> String?``` -- всё после хоста: path + query + fragment
+* ```Url::GetPath(String?) -> String?```
+* ```Url::GetFragment(String?) -> String?```
+* ```Url::GetCGIParam(String?, String) -> String?``` -- второй параметр — имя нужного CGI параметра
+* ```Url::GetDomain(String?, Uint8) -> String?``` -- второй параметр — необходимый уровень домена
+* ```Url::GetTLD(String{Flags:AutoMap}) -> String```
+* ```Url::IsKnownTLD(String{Flags:AutoMap}) -> Bool``` -- зарегистрирован на http://www.iana.org/
+* ```Url::IsWellKnownTLD(String{Flags:AutoMap}) -> Bool``` -- находится в небольшом whitelist из com, net, org, ru и пр.
+* ```Url::GetDomainLevel(String{Flags:AutoMap}) -> Uint64```
+* ```Url::GetSignificantDomain(String{Flags:AutoMap}, [List<String>?]) -> String```
+ Возвращает домен второго уровня в большинстве случаев и домен третьего уровня для хостеймов вида: ***.XXX.YY, где XXX — одно из com, net, org, co, gov, edu. Этот список можно переопределить через опциональный второй аргумент
+
+* ```Url::GetOwner(String{Flags:AutoMap}) -> String```
+ Возвращает домен, которым с наибольшей вероятностью владеет отдельный человек или организация. В отличие от Url::GetSignificantDomain работает по специальному whitelist, и помимо доменов из серии ***.co.uk возвращает домен третьего уровня для, например, бесплатных хостингов и блогов, скажем something.livejournal.com
+
+**Примеры**
+
+```sql
+SELECT Url::GetScheme("https://ya.ru"); -- "https://"
+SELECT Url::GetDomain("http://www.yandex.ru", 2); -- "yandex.ru"
+```
+
+## Cut... {#cut}
+
+* ```Url::CutScheme(String?) -> String?```
+ Возвращает переданный URL уже без схемы (http://, https:// и т.п.).
+
+* ```Url::CutWWW(String?) -> String?```
+ Возвращает переданный домен без префикса "www.", если он имелся.
+
+* ```Url::CutWWW2(String?) -> String?```
+Возвращает переданный домен без префикса "www.", "www2.", "wwww777." и тому подобных, если он имелся.
+
+* ```Url::CutQueryStringA­ndFragment(String{Flags:AutoMap}) -> String```
+ Возращает копию переданного URL с удаленными всеми CGI параметрами и фрагментами ("?foo=bar" и/или "#baz").
+
+**Примеры**
+
+```sql
+SELECT Url::CutScheme("http://www.yandex.ru"); -- "www.yandex.ru"
+SELECT Url::CutWWW("www.yandex.ru"); -- "yandex.ru"
+```
+
+## ...Punycode... {#punycode}
+
+Преобразования [Punycode](https://en.wikipedia.org/wiki/Punycode).
+
+**Список функций**
+
+* ```Url::HostNameToPunycode(String{Flag:AutoMap}) -> String?```
+* ```Url::ForceHostNameToPunycode(String{Flag:AutoMap}) -> String```
+* ```Url::PunycodeToHostName(String{Flag:AutoMap}) -> String?```
+* ```Url::ForcePunycodeToHostName(String{Flag:AutoMap}) -> String```
+* ```Url::CanBePunycodeHostName(String{Flag:AutoMap}) -> Bool```
+
+**Примеры**
+
+```sql
+SELECT Url::PunycodeToHostName("xn--d1acpjx3f.xn--p1ai"); -- "яндекс.рф"
+```
+
+## ...Query... {#query}
+
+Преобразования [Query](https://docs.python.org/3/library/urllib.parse.html).
+
+**Список функций**
+
+```sql
+Url::QueryStringToList(String{Flag:AutoMap}, [
+ KeepBlankValues:Bool?, -- пустые значения в percent-encoded запросах интерпретируются как пустыe строки; по умолчанию false
+ Strict:Bool?, -- если false - ошибки парсинга игнорируются, ошибочные поля пропускаются; по умолчанию true
+ MaxFields:Uint32?, -- максимальное количество полей, при превышении кидается исключение; по умолчанию Max<Uint32>
+ Separator:String? -- разделитель пар ключ-значение; по умолчанию '&'
+]) -> List<Tuple<String, String>>
+Url::QueryStringToDict(String{Flag:AutoMap}, [
+ KeepBlankValues:Bool?, -- пустые значения в percent-encoded запросах интерпретируются как пустыe строки; по умолчанию false
+ Strict:Bool?, -- если false - ошибки парсинга игнорируются, ошибочные поля пропускаются; по умолчанию true
+ MaxFields:Uint32?, -- максимальное количество полей, при превышении кидается исключение; по умолчанию Max<Uint32>
+ Separator:String? -- разделитель пар ключ-значение; по умолчанию '&'
+]) -> Dict<String, List<String>>
+Url::BuildQueryString(Dict<String, List<String?>>{Flag:AutoMap}, [
+ Separator:String? -- разделитель пар ключ-значение; по умолчанию '&'
+]) -> String
+Url::BuildQueryString(Dict<String, String?>{Flag:AutoMap}, [
+ Separator:String? -- разделитель пар ключ-значение; по умолчанию '&'
+]) -> String
+Url::BuildQueryString(List<Tuple<String, String?>>{Flag:AutoMap}, [
+ Separator:String? -- разделитель пар ключ-значение; по умолчанию '&'
+]) -> String
+```
+
+**Примеры**
+```sql
+SELECT Url::QueryStringToList("a=1&b=2&a=3"); -- [("a", "1"), ("b", "2"), ("a", "3")]
+SELECT Url::QueryStringToDict("a=1&b=2&a=3"); -- {"b" : ["2"], "a" : ["1", "3"]}
+SELECT Url::BuildQueryString([("a", "1"), ("a", "3"), ("b", "2")]); -- "a=1&a=3&b=2"
+SELECT Url::BuildQueryString({"a" : "1", "b" : "2"}); -- "b=2&a=1"
+SELECT Url::BuildQueryString({"a" : ["1", "3"], "b" : ["2", "4"]}); -- "b=2&b=4&a=1&a=3"
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/intro_footer.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/intro_footer.md
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/intro_footer.md
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/intro_header.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/intro_header.md
new file mode 100644
index 00000000000..78f522f214d
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/intro_header.md
@@ -0,0 +1 @@
+YSON — разработанный в Яндексе формат данных, похожий на JSON. \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/ypath_overlay.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/ypath_overlay.md
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/_includes/yson/ypath_overlay.md
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/datetime.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/datetime.md
new file mode 100644
index 00000000000..96d6ec3315e
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/datetime.md
@@ -0,0 +1,469 @@
+# DateTime
+
+В модуле DateTime основным внутренним форматом представления является `Resource<TM>`, хранящий следующие компоненты даты:
+
+* Year (12 бит);
+* Month (4 бита);
+* Day (5 бит);
+* Hour (5 бит);
+* Minute (6 бит);
+* Second (6 бит);
+* Microsecond (20 бит);
+* TimezoneId (16 бит);
+* DayOfYear (9 бит) — день от начала года;
+* WeekOfYear (6 бит) — неделя от начала года, 1 января всегда относится к первой неделе;
+* WeekOfYearIso8601 (6 бит) — неделя года согласно ISO 8601 (первой неделей считается та, в которой 4 января)
+* DayOfWeek (3 бита) — день недели.
+
+Если таймзона не GMT, то в компонентах хранится локальное время в соответствующей таймзоне.
+
+## Split {#split}
+
+Преобразование из простого типа во внутреннее представление. Всегда успешно при непустом входе.
+
+**Список функций**
+
+* ```DateTime::Split(Date{Flags:AutoMap}) -> Resource<TM>```
+* ```DateTime::Split(Datetime{Flags:AutoMap}) -> Resource<TM>```
+* ```DateTime::Split(Timestamp{Flags:AutoMap}) -> Resource<TM>```
+* ```DateTime::Split(TzDate{Flags:AutoMap}) -> Resource<TM>```
+* ```DateTime::Split(TzDatetime{Flags:AutoMap}) -> Resource<TM>```
+* ```DateTime::Split(TzTimestamp{Flags:AutoMap}) -> Resource<TM>```
+
+Функции, принимающие на вход `Resource<TM>`, могут быть вызваны непосредственно от простого типа даты/времени. В этом случае будет сделано неявное преобразование через вызов соответствующей функции `Split`.
+
+## Make... {#make}
+
+Сборка простого типа из внутреннего представления. Всегда успешна при непустом входе.
+
+**Список функций**
+
+* ```DateTime::MakeDate(Resource<TM>{Flags:AutoMap}) -> Date```
+* ```DateTime::MakeDatetime(Resource<TM>{Flags:AutoMap}) -> Datetime```
+* ```DateTime::MakeTimestamp(Resource<TM>{Flags:AutoMap}) -> Timestamp```
+* ```DateTime::MakeTzDate(Resource<TM>{Flags:AutoMap}) -> TzDate```
+* ```DateTime::MakeTzDatetime(Resource<TM>{Flags:AutoMap}) -> TzDatetime```
+* ```DateTime::MakeTzTimestamp(Resource<TM>{Flags:AutoMap}) -> TzTimestamp```
+
+**Примеры**
+
+``` yql
+SELECT
+ DateTime::MakeTimestamp(DateTime::Split(Datetime("2019-01-01T15:30:00Z"))),
+ -- 2019-01-01T15:30:00.000000Z
+ DateTime::MakeDate(Datetime("2019-01-01T15:30:00Z")),
+ -- 2019-01-01
+ DateTime::MakeTimestamp(DateTime::Split(TzDatetime("2019-01-01T00:00:00,Europe/Moscow"))),
+ -- 2018-12-31T21:00:00Z (конвертация в UTC)
+ DateTime::MakeDate(TzDatetime("2019-01-01T12:00:00,GMT"))
+ -- 2019-01-01 (Datetime -> Date с неявным Split)
+```
+
+## Get... {#get}
+
+Взятие компоненты внутреннего представления.
+
+**Список функций**
+
+* ```DateTime::GetYear(Resource<TM>{Flags:AutoMap}) -> Uint16```
+* ```DateTime::GetDayOfYear(Resource<TM>{Flags:AutoMap}) -> Uint16```
+* ```DateTime::GetMonth(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetMonthName(Resource<TM>{Flags:AutoMap}) -> String```
+* ```DateTime::GetWeekOfYear(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetWeekOfYearIso8601(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetDayOfMonth(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetDayOfWeek(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetDayOfWeekName(Resource<TM>{Flags:AutoMap}) -> String```
+* ```DateTime::GetHour(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetMinute(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetSecond(Resource<TM>{Flags:AutoMap}) -> Uint8```
+* ```DateTime::GetMillisecondOfSecond(Resource<TM>{Flags:AutoMap}) -> Uint32```
+* ```DateTime::GetMicrosecondOfSecond(Resource<TM>{Flags:AutoMap}) -> Uint32```
+* ```DateTime::GetTimezoneId(Resource<TM>{Flags:AutoMap}) -> Uint16```
+* ```DateTime::GetTimezoneName(Resource<TM>{Flags:AutoMap}) -> String```
+
+**Примеры**
+
+``` yql
+$tm = DateTime::Split(TzDatetime("2019-01-09T00:00:00,Europe/Moscow"));
+
+SELECT
+ DateTime::GetDayOfMonth($tm) as Day, -- 9
+ DateTime::GetMonthName($tm) as Month, -- "January"
+ DateTime::GetYear($tm) as Year, -- 2019
+ DateTime::GetTimezoneName($tm) as TzName, -- "Europe/Moscow"
+ DateTime::GetDayOfWeekName($tm) as WeekDay; -- "Wednesday"
+```
+
+## Update {#update}
+
+Обновление одной или нескольких компонент во внутреннем представлении. Возвращает либо обновлённую копию, либо NULL, если после обновления получается некорректная дата или возникают другие противоречия.
+
+**Список функций**
+
+* ```DateTime::Update( Resource<TM>{Flags:AutoMap}, [ Year:Uint16?, Month:Uint8?, Day:Uint8?, Hour:Uint8?, Minute:Uint8?, Second:Uint8?, Microsecond:Uint32?, Timezone:String? ]) -> Resource<TM>?```
+
+**Примеры**
+
+``` yql
+$tm = DateTime::Split(Timestamp("2019-01-01T01:02:03.456789Z"));
+
+SELECT
+ DateTime::MakeDate(DateTime::Update($tm, 2012)), -- 2012-01-01
+ DateTime::MakeDate(DateTime::Update($tm, 2000, 6, 6)), -- 2000-06-06
+ DateTime::MakeDate(DateTime::Update($tm, NULL, 2, 30)), -- NULL (30 февраля)
+ DateTime::MakeDatetime(DateTime::Update($tm, NULL, NULL, 31)), -- 2019-01-31T01:02:03Z
+ DateTime::MakeDatetime(DateTime::Update($tm, 15 as Hour, 30 as Minute)), -- 2019-01-01T15:30:03Z
+ DateTime::MakeTimestamp(DateTime::Update($tm, 999999 as Microsecond)), -- 2019-01-01T01:02:03.999999Z
+ DateTime::MakeTimestamp(DateTime::Update($tm, "Europe/Moscow" as Timezone)), -- 2018-12-31T22:02:03.456789Z (конвертация в UTC)
+ DateTime::MakeTzTimestamp(DateTime::Update($tm, "Europe/Moscow" as Timezone)); -- 2019-01-01T01:02:03.456789,Europe/Moscow
+```
+
+## From... {#from}
+
+Получение Timestamp из количества секунд/миллисекунд/микросекунд от начала эпохи в UTC. При выходе за границы Timestamp возвращается NULL.
+
+**Список функций**
+
+* ```DateTime::FromSeconds(Uint32{Flags:AutoMap}) -> Timestamp```
+* ```DateTime::FromMilliseconds(Uint64{Flags:AutoMap}) -> Timestamp```
+* ```DateTime::FromMicroseconds(Uint64{Flags:AutoMap}) -> Timestamp```
+
+## To... {#to}
+
+Получение количества секунд/миллисекунд/микросекунд от начала эпохи в UTC из простого типа.
+
+**Список функций**
+
+* ```DateTime::ToSeconds(Date/DateTime/Timestamp/TzDate/TzDatetime/TzTimestamp{Flags:AutoMap}) -> Uint32```
+* ```DateTime::ToMilliseconds(Date/DateTime/Timestamp/TzDate/TzDatetime/TzTimestamp{Flags:AutoMap}) -> Uint64```
+* ```DateTime::ToMicroseconds(Date/DateTime/Timestamp/TzDate/TzDatetime/TzTimestamp{Flags:AutoMap}) -> Uint64```
+
+**Примеры**
+
+``` yql
+SELECT
+ DateTime::FromSeconds(1546304523), -- 2019-01-01T01:02:03.000000Z
+ DateTime::ToMicroseconds(Timestamp("2019-01-01T01:02:03.456789Z")); -- 1546304523456789
+```
+## Interval... {#interval}
+
+Преобразования между ```Interval``` и различными единицами измерения времени.
+
+**Список функций**
+
+* ```DateTime::ToDays(Interval{Flags:AutoMap}) -> Int16```
+* ```DateTime::ToHours(Interval{Flags:AutoMap}) -> Int32```
+* ```DateTime::ToMinutes(Interval{Flags:AutoMap}) -> Int32```
+* ```DateTime::ToSeconds(Interval{Flags:AutoMap}) -> Int32```
+* ```DateTime::ToMilliseconds(Interval{Flags:AutoMap}) -> Int64```
+* ```DateTime::ToMicroseconds(Interval{Flags:AutoMap}) -> Int64```
+* ```DateTime::IntervalFromDays(Int16{Flags:AutoMap}) -> Interval```
+* ```DateTime::IntervalFromHours(Int32{Flags:AutoMap}) -> Interval```
+* ```DateTime::IntervalFromMinutes(Int32{Flags:AutoMap}) -> Interval```
+* ```DateTime::IntervalFromSeconds(Int32{Flags:AutoMap}) -> Interval```
+* ```DateTime::IntervalFromMilliseconds(Int64{Flags:AutoMap}) -> Interval```
+* ```DateTime::IntervalFromMicroseconds(Int64{Flags:AutoMap}) -> Interval```
+
+AddTimezone никак не влияет на вывод ToSeconds(), поскольку ToSeconds() всегда возвращают время в таймзоне GMT.
+
+Interval также можно создавать из строкового литерала в формате [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601%23Durations).
+
+**Примеры**
+
+``` yql
+SELECT
+ DateTime::ToDays(Interval("PT3000M")), -- 2
+ DateTime::IntervalFromSeconds(1000000), -- 11 days 13 hours 46 minutes 40 seconds
+ DateTime::ToDays(cast('2018-01-01' as date) - cast('2017-12-31' as date)); --1
+```
+
+## StartOf... / TimeOfDay {#startof}
+
+Получить начало периода, содержащего дату/время. При некорректном результате возвращается NULL. Если таймзона не GMT, то начало периода будет в указанной временной зоне.
+
+**Список функций**
+
+* ```DateTime::StartOfYear(Resource<TM>{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::StartOfQuarter(Resource<TM>{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::StartOfMonth(Resource<TM>{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::StartOfWeek(Resource<TM>{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::StartOfDay(Resource<TM>{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::StartOf(Resource<TM>{Flags:AutoMap}, Interval{Flags:AutoMap}) -> Resource<TM>?```
+
+Функция `StartOf` предназначена для группировки в пределах суток по произвольному периоду. Результат отличается от входного значения только компонентами времени. Период более суток трактуется как сутки (эквивалентно `StartOfDay`). Если в сутках не содержится целого числа периодов, производится округление к ближайшему времени от начала суток, кратному указанному периоду. При нулевом интервале выход совпадает со входом. Отрицательный интервал трактуется как положительный.
+
+Поведение функций с периодами больше дня отличается от поведения одноимённых функций в старой библиотеке. Компоненты времени всегда обнуляются (это логично, поскольку эти функции в основном используются для группировки по периоду). Отдельно существует возможность выделить время в пределах суток:
+
+* ```DateTime::TimeOfDay(Resource<TM>{Flags:AutoMap}) -> Interval```
+
+**Примеры**
+
+``` yql
+SELECT
+ DateTime::MakeDate(DateTime::StartOfYear(Date("2019-06-06"))),
+ -- 2019-01-01 (неявный Split здесь и дальше)
+ DateTime::MakeDatetime(DateTime::StartOfQuarter(Datetime("2019-06-06T01:02:03Z"))),
+ -- 2019-04-01T00:00:00Z (компоненты времени обнулены)
+ DateTime::MakeDate(DateTime::StartOfMonth(Timestamp("2019-06-06T01:02:03.456789Z"))),
+ -- 2019-06-01
+ DateTime::MakeDate(DateTime::StartOfWeek(Date("1970-01-01"))),
+ -- NULL (начало эпохи - четверг, начало недели - 1969-12-29, выход за границы)
+ DateTime::MakeTimestamp(DateTime::StartOfWeek(Date("2019-01-01"))),
+ -- 2018-12-31T00:00:00Z
+ DateTime::MakeDatetime(DateTime::StartOfDay(Datetime("2019-06-06T01:02:03Z"))),
+ -- 2019-06-06T00:00:00Z
+ DateTime::MakeTzDatetime(DateTime::StartOfDay(TzDatetime("1970-01-01T05:00:00,Europe/Moscow"))),
+ -- NULL (в GMT выход за эпоху)
+ DateTime::MakeTzTimestamp(DateTime::StartOfDay(TzTimestamp("1970-01-02T05:00:00.000000,Europe/Moscow"))),
+ -- 1970-01-02T00:00:00,Europe/Moscow (начало дня по Москве)
+ DateTime::MakeDatetime(DateTime::StartOf(Datetime("2019-06-06T23:45:00Z"), Interval("PT7H"))),
+ -- 2019-06-06T21:00:00Z
+ DateTime::MakeDatetime(DateTime::StartOf(Datetime("2019-06-06T23:45:00Z"), Interval("PT20M"))),
+ -- 2019-06-06T23:40:00Z
+ DateTime::TimeOfDay(Timestamp("2019-02-14T01:02:03.456789Z"));
+ -- 1 hour 2 minutes 3 seconds 456789 microseconds
+```
+
+## Shift... {#shift}
+
+Прибавить/вычесть заданное количество единиц к компоненте во внутреннем представлении и обновить остальные поля.
+Возвращает либо обновлённую копию, либо NULL, если после обновления получается некорректная дата или возникают другие противоречия.
+
+**Список функций**
+
+* ```DateTime::ShiftYears(Resource<TM>{Flags:AutoMap}, Int32) -> Resource<TM>?```
+* ```DateTime::ShiftQuarters(Resource<TM>{Flags:AutoMap}, Int32) -> Resource<TM>?```
+* ```DateTime::ShiftMonths(Resource<TM>{Flags:AutoMap}, Int32) -> Resource<TM>?```
+
+Если в результате номер дня в месяце превышает максимально возможный, то в поле `Day` будет записан последний день месяца,
+время при этом не изменится (см. примеры).
+
+**Примеры**
+
+``` yql
+$tm1 = DateTime::Split(DateTime("2019-01-31T01:01:01Z"));
+$tm2 = DateTime::Split(TzDatetime("2049-05-20T12:34:50,Europe/Moscow"));
+
+SELECT
+ DateTime::MakeDate(DateTime::ShiftYears($tm1, 10)), -- 2029-01-31T01:01:01
+ DateTime::MakeDate(DateTime::ShiftYears($tm2, -10000)), -- NULL (выход за границы)
+ DateTime::MakeDate(DateTime::ShiftQuarters($tm2, 0)), -- 2049-05-20T12:34:50,Europe/Moscow
+ DateTime::MakeDate(DateTime::ShiftQuarters($tm1, -3)), -- 2018-04-30T01:01:01
+ DateTime::MakeDate(DateTime::ShiftMonths($tm1, 1)), -- 2019-02-28T01:01:01
+ DateTime::MakeDate(DateTime::ShiftMonths($tm1, -35)), -- 2016-02-29T01:01:01
+```
+
+## Format {#format}
+
+Получить строковое представление момента времени, используя произвольную строку форматирования.
+
+**Список функций**
+
+* ```DateTime::Format(String) -> (Resource<TM>{Flags:AutoMap}) -> String```
+
+Для строки форматирования реализовано подмножество спецификаторов, аналогичных strptime.
+
+* `%%` - символ %;
+* `%Y` - год 4 цифры;
+* `%m` - месяц 2 цифры;
+* `%d` - день 2 цифры;
+* `%H` - час 2 цифры;
+* `%M` - минуты 2 цифры;
+* `%S` - секунды 2 цифры -- или xx.xxxxxx в случае непустых микросекунд;
+* `%z` - +hhmm or -hhmm;
+* `%Z` - IANA имя таймзоны;
+* `%b` - короткое трехбуквенное английское название месяца (Jan);
+* `%B` - полное английское название месяца (January).
+
+Все остальные символы строки форматирования переносятся без изменений.
+
+**Примеры**
+
+``` yql
+$format = DateTime::Format("%Y-%m-%d %H:%M:%S %Z");
+
+SELECT
+ $format(DateTime::Split(TzDatetime("2019-01-01T01:02:03,Europe/Moscow")));
+ -- "2019-01-01 01:02:03 Europe/Moscow"
+```
+
+## Parse {#parse}
+
+Распарсить строку во внутреннее представление, используя произвольную строку форматирования. Для незаполненных полей используются значения по умолчанию. При возникновении ошибок возвращается NULL.
+
+**Список функций**
+
+* ```DateTime::Parse(String) -> (String{Flags:AutoMap}) -> Resource<TM>?```
+
+Реализованные спецификаторы:
+
+* `%%` - символ %;
+* `%Y` - год 4 цифры (1970);
+* `%m` - месяц 2 цифры (1);
+* `%d` - день 2 цифры (1);
+* `%H` - час 2 цифры (0);
+* `%M` - минуты 2 цифры (0);
+* `%S` - секунды (0), может принимать и микросекунды в форматах от xx. до xx.xxxxxx
+* `%Z` - IANA имя таймзоны (GMT).
+* `%b` - короткое трехбуквенное регистронезависимое английское название месяца (Jan);
+* `%B` - полное регистронезависимое английское название месяца (January).
+
+**Примеры**
+
+``` yql
+$parse1 = DateTime::Parse("%H:%M:%S");
+$parse2 = DateTime::Parse("%S");
+$parse3 = DateTime::Parse("%m/%d/%Y");
+$parse4 = DateTime::Parse("%Z");
+
+SELECT
+ DateTime::MakeDatetime($parse1("01:02:03")), -- 1970-01-01T01:02:03Z
+ DateTime::MakeTimestamp($parse2("12.3456")), -- 1970-01-01T00:00:12.345600Z
+ DateTime::MakeTimestamp($parse3("02/30/2000")), -- NULL (Feb 30)
+ DateTime::MakeTimestamp($parse4("Canada/Central")); -- 1970-01-01T06:00:00Z (конвертация в UTC)
+```
+
+Для распространённых форматов есть врапперы вокруг соответствующих методов util. Можно получить только TM с компонентами в UTC таймзоне.
+
+**Список функций**
+
+* ```DateTime::ParseRfc822(String{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::ParseIso8601(String{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::ParseHttp(String{Flags:AutoMap}) -> Resource<TM>?```
+* ```DateTime::ParseX509(String{Flags:AutoMap}) -> Resource<TM>?```
+
+**Примеры**
+
+``` yql
+SELECT
+ DateTime::MakeTimestamp(DateTime::ParseRfc822("Fri, 4 Mar 2005 19:34:45 EST")),
+ -- 2005-03-05T00:34:45Z
+ DateTime::MakeTimestamp(DateTime::ParseIso8601("2009-02-14T02:31:30+0300")),
+ -- 2009-02-13T23:31:30Z
+ DateTime::MakeTimestamp(DateTime::ParseHttp("Sunday, 06-Nov-94 08:49:37 GMT")),
+ -- 1994-11-06T08:49:37Z
+ DateTime::MakeTimestamp(DateTime::ParseX509("20091014165533Z"))
+ -- 2009-10-14T16:55:33Z
+```
+
+## Типовые сценарии
+
+**Преобразования между строками и секундами**
+
+Преобразование строковой даты (в таймзоне Москвы) в секунды (в таймзоне GMT):
+
+``` yql
+$datetime_parse = DateTime::Parse("%Y-%m-%d %H:%M:%S");
+$datetime_parse_tz = DateTime::Parse("%Y-%m-%d %H:%M:%S %Z");
+
+SELECT
+ DateTime::ToSeconds(TzDateTime("2019-09-16T00:00:00,Europe/Moscow")) AS md_us1, -- 1568581200
+ DateTime::ToSeconds(DateTime::MakeDatetime($datetime_parse_tz("2019-09-16 00:00:00" || " Europe/Moscow"))), -- 1568581200
+ DateTime::ToSeconds(DateTime::MakeDatetime(DateTime::Update($datetime_parse("2019-09-16 00:00:00"), "Europe/Moscow" as Timezone))), -- 1568581200
+
+ -- НЕПРАВИЛЬНО (Date импортирует время как GMT, а AddTimezone никак не влияет на ToSeconds, которая всегда возвращает время в таймзоне GMT)
+ DateTime::ToSeconds(AddTimezone(Date("2019-09-16"), 'Europe/Moscow')) AS md_us2, -- 1568592000
+```
+
+Преобразование строковой даты (в таймзоне Москвы) в секунды (в таймзоне Москвы). Поскольку DateTime::ToSeconds() экспортирует только GMT, придется временно забыть о таймзонах и работать только в GMT (выглядит это так, как будто временно мы считаем, что в Москве таймзона GMT):
+
+``` yql
+$date_parse = DateTime::Parse("%Y-%m-%d");
+$datetime_parse = DateTime::Parse("%Y-%m-%d %H:%M:%S");
+$datetime_parse_tz = DateTime::Parse("%Y-%m-%d %H:%M:%S %Z");
+
+SELECT
+ DateTime::ToSeconds(Datetime("2019-09-16T00:00:00Z")) AS md_ms1, -- 1568592000
+ DateTime::ToSeconds(Date("2019-09-16")) AS md_ms2, -- 1568592000
+ DateTime::ToSeconds(DateTime::MakeDatetime($date_parse("2019-09-16"))) AS md_ms3, -- 1568592000
+ DateTime::ToSeconds(DateTime::MakeDatetime($datetime_parse("2019-09-16 00:00:00"))) AS md_ms4, -- 1568592000
+ DateTime::ToSeconds(DateTime::MakeDatetime($datetime_parse_tz("2019-09-16 00:00:00 GMT"))) AS md_ms5, -- 1568592000
+
+ -- НЕПРАВИЛЬНО (импортирует время в таймзоне Москвы, а RemoveTimezone никак не влияет на ToSeconds)
+ DateTime::ToSeconds(RemoveTimezone(TzDatetime("2019-09-16T00:00:00,Europe/Moscow"))) AS md_ms6, -- 1568581200
+ DateTime::ToSeconds(DateTime::MakeDatetime($datetime_parse_tz("2019-09-16 00:00:00 Europe/Moscow"))) AS md_ms7 -- 1568581200
+```
+
+Преобразование секунд (в таймзоне GMT) в строковую дату (в таймзоне Москвы):
+``` yql
+$date_format = DateTime::Format("%Y-%m-%d %H:%M:%S %Z");
+SELECT
+ $date_format(AddTimezone(DateTime::FromSeconds(1568592000), 'Europe/Moscow')) -- "2019-09-16 03:00:00 Europe/Moscow"
+```
+
+Преобразование секунд (в таймзоне Москвы) в строковую дату (в таймзоне Москвы). Здесь таймзона %Z выводится для справки - обычно выводить ее не нужно, потому что она будет равна "GMT" и может сбить с толку.
+``` yql
+$date_format = DateTime::Format("%Y-%m-%d %H:%M:%S %Z");
+SELECT
+ $date_format(DateTime::FromSeconds(1568592000)) -- "2019-09-16 00:00:00 GMT"
+```
+
+Преобразование секунд (в таймзоне GMT) в трехбуквенное название дня недели (в таймзоне Москвы):
+``` yql
+SELECT
+ SUBSTRING(DateTime::GetDayOfWeekName(AddTimezone(DateTime::FromSeconds(1568581200), "Europe/Moscow")), 0, 3) -- "Mon"
+```
+
+**Форматирование даты и времени**
+
+Обычно для форматирования времени используется отдельное именованное выражение, но можно обойтись и без него:
+
+``` yql
+$date_format = DateTime::Format("%Y-%m-%d %H:%M:%S %Z");
+
+SELECT
+
+ -- Вариант с именованным выражением
+
+ $date_format(AddTimezone(DateTime::FromSeconds(1568592000), 'Europe/Moscow')),
+
+ -- Вариант без именованного выражения
+
+ DateTime::Format("%Y-%m-%d %H:%M:%S %Z")
+ (AddTimezone(DateTime::FromSeconds(1568592000), 'Europe/Moscow'))
+;
+```
+
+**Преобразование типов**
+
+Так можно преобразовывать только константы:
+
+``` yql
+SELECT
+ TzDateTime("2019-09-16T00:00:00,Europe/Moscow"), -- 2019-09-16T00:00:00,Europe/Moscow
+ Date("2019-09-16") -- 2019-09-16
+```
+
+А так - константу, именованное выражение или поле таблицы:
+
+``` yql
+SELECT
+ CAST("2019-09-16T00:00:00,Europe/Moscow" AS TzDateTime), -- 2019-09-16T00:00:00,Europe/Moscow
+ CAST("2019-09-16" AS Date) -- 2019-09-16
+```
+
+**Преобразование времени в дату**
+
+CAST в Date или TzDate дает такую дату в таймзоне GMT, в которую происходит полночь по локальному времени (например, для московского времени 2019-10-22 00:00:00, будет возвращена дата 2019-10-21). Для получения даты в локальной таймзоне можно использовать DateTime::Format.
+
+``` yql
+$x = DateTime("2019-10-21T21:00:00Z");
+select
+ AddTimezone($x, "Europe/Moscow"), -- 2019-10-22T00:00:00,Europe/Moscow
+ cast($x as TzDate), -- 2019-10-21,GMT
+ cast(AddTimezone($x, "Europe/Moscow") as TzDate), -- 2019-10-21,Europe/Moscow
+ cast(AddTimezone($x, "Europe/Moscow") as Date), -- 2019-10-21
+ DateTime::Format("%Y-%m-%d %Z")(AddTimezone($x, "Europe/Moscow")), -- 2019-10-22 Europe/Moscow
+```
+
+**Летнее время**
+
+Обратите внимание, что летнее время зависит от года:
+
+``` yql
+SELECT
+ RemoveTimezone(TzDatetime("2019-09-16T10:00:00,Europe/Moscow")) as DST1, -- 2019-09-16T07:00:00Z
+ RemoveTimezone(TzDatetime("2008-12-03T10:00:00,Europe/Moscow")) as DST2, -- 2008-12-03T07:00:00Z
+ RemoveTimezone(TzDatetime("2008-07-03T10:00:00,Europe/Moscow")) as DST3, -- 2008-07-03T06:00:00Z (DST)
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/digest.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/digest.md
new file mode 100644
index 00000000000..ee618c170fc
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/digest.md
@@ -0,0 +1,38 @@
+# Digest
+
+Набор распространенных хеш-функций.
+
+**Список функций**
+
+* ```Digest::Crc32c(String{Flags::AutoMap}) -> Uint32```
+* ```Digest::Fnv32(String{Flags::AutoMap}) -> Uint32```
+* ```Digest::Fnv64(String{Flags::AutoMap}) -> Uint64```
+* ```Digest::MurMurHash(String{Flags:AutoMap}) -> Uint64```
+* ```Digest::CityHash(String{Flags:AutoMap}) -> Uint64```
+* ```Digest::CityHash128(String{Flags:AutoMap}) -> Tuple<Uint64,Uint64>```
+* ```Digest::NumericHash(Uint64{Flags:AutoMap}) -> Uint64```
+* ```Digest::Md5Hex(String{Flags:AutoMap}) -> String```
+* ```Digest::Md5Raw(String{Flags:AutoMap}) -> String```
+* ```Digest::Md5HalfMix(String{Flags:AutoMap}) -> Uint64``` - вариант огрубления MD5 (yabs_md5)
+* ```Digest::Argon2(String{Flags:AutoMap},String{Flags:AutoMap}) -> String``` - вторым аргументом salt
+* ```Digest::Blake2B(String{Flags:AutoMap},[String?]) -> String``` - вторым опциональным аргументом ключ
+* ```Digest::SipHash(Uint64,Uint64,String{Flags:AutoMap}) -> Uint64```
+* ```Digest::HighwayHash(Uint64,Uint64,Uint64,Uint64,String{Flags:AutoMap}) -> Uint64```
+* ```Digest::FarmHashFingerprint(Uint64{Flags:AutoMap}) -> Uint64```
+* ```Digest::FarmHashFingerprint2(Uint64{Flags:AutoMap}, Uint64{Flags:AutoMap}) -> Uint64```
+* ```Digest::FarmHashFingerprint32(String{Flags:AutoMap}) -> Uint32```
+* ```Digest::FarmHashFingerprint64(String{Flags:AutoMap}) -> Uint64```
+* ```Digest::FarmHashFingerprint128(String{Flags:AutoMap}) -> Tuple<Uint64,Uint64>```
+* ```Digest::SuperFastHash(String{Flags:AutoMap}) -> Uint32```
+* ```Digest::Sha1(String{Flags:AutoMap}) -> String```
+* ```Digest::Sha256(String{Flags:AutoMap}) -> String```
+* ```Digest::IntHash64(Uint64{Flags:AutoMap}) -> Uint64```
+* ```Digest::XXH3(String{Flags:AutoMap}) -> Uint64```
+* ```Digest::XXH3_128(String{Flags:AutoMap}) -> Tuple<Uint64,Uint64>```
+
+**Примеры**
+
+``` sql
+SELECT Digest::Md5Hex("YQL"); -- "1a0c1b56e9d617688ee345da4030da3c"
+SELECT Digest::NumericHash(123456789); -- 1734215268924325803
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/histogram.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/histogram.md
new file mode 100644
index 00000000000..921030daeb7
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/histogram.md
@@ -0,0 +1,2 @@
+
+{% include[x](_includes/histogram.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/hyperscan.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/hyperscan.md
new file mode 100644
index 00000000000..34cbe7c89c8
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/hyperscan.md
@@ -0,0 +1,127 @@
+# Hyperscan
+
+[Hyperscan](https://www.hyperscan.io) является opensource библиотекой для поиска по регулярным выражениям, разработанной компанией Intel.
+
+Библиотека имеет 4 реализации с использованием разных наборов процессорных инструкций (SSE3, SSE4.2, AVX2 и AVX512), среди которых автоматически выбирается нужная в соответствии с текущим процессором.
+
+По умолчанию все функции работают в однобайтовом режиме, но если регулярное выражение является валидной UTF-8 строкой, но не является валидной ASCII строкой, — автоматически включается режим UTF-8.
+
+**Список функций**
+
+* ```Hyperscan::Grep(String) -> (String?) -> Bool```
+* ```Hyperscan::Match(String) -> (String?) -> Bool```
+* ```Hyperscan::BacktrackingGrep(String) -> (String?) -> Bool```
+* ```Hyperscan::BacktrackingMatch(String) -> (String?) -> Bool```
+* ```Hyperscan::MultiGrep(String) -> (String?) -> Tuple<Bool, Bool, ...>```
+* ```Hyperscan::MultiMatch(String) -> (String?) -> Tuple<Bool, Bool, ...>```
+* ```Hyperscan::Capture(String) -> (String?) -> String?```
+* ```Hyperscan::Replace(String) -> (String?, String) -> String?```
+
+## Синтаксис вызова {#syntax}
+
+При вызове напрямую, чтобы избежать компиляции регулярного выражения на каждой строке таблицы, необходимо обернуть вызов функции в [именованное выражение](../../syntax/expressions.md#named-nodes):
+
+``` sql
+$re = Hyperscan::Grep("\\d+"); -- создаем вызываемое значение для проверки конкретного регулярного выражения
+SELECT * FROM table WHERE $re(key); -- используем его для фильтрации таблицы
+```
+
+**Обратите внимание** на экранирование спецсимволов в регулярном выражении. Второй слеш нужен, так как все стандартные строковые литералы в SQL могут принимать С-escaped строки, а последовательность `\d` не является валидной последовательностью, и даже если бы являлась — не приводила бы к ожидаемому эффекту поиска чисел.
+
+Есть возможность отключить чувствительность к регистру (то есть включить case-insensitive режим), указав в начале регулярного выражения флаг `(?i)`.
+
+
+
+## Grep {#grep}
+
+Проверяет совпадение регулярного выражения с **частью строки** (произвольной подстрокой).
+
+Функцию `Hyperscan::Grep` можно вызвать с помощью выражения `REGEXP` (см. [описание базового синтаксиса выражений](../../syntax/expressions.md#regexp)).
+
+Например, следующие два запроса эквивалентны (в том числе по эффективности вычислений):
+
+* ```$grep = Hyperscan::Grep("b+"); SELECT $grep("aaabccc");```
+* ```SELECT "aaabccc" REGEXP "b+";```
+
+## Match {#match}
+
+Проверяет совпадение регулярного выражения **со строкой целиком**.
+
+Чтобы получить результат аналогичный `Grep` (где учитывается совпадение с подстрокой), нужно обрамлять регулярное выражение с обеих сторон в `.*` (`.*foo.*` вместо `foo`). Однако, с точки зрения читабельности кода, обычно лучше поменять функцию.
+
+## BacktrackingGrep / BacktrackingMatch {#backtrackinggrep}
+
+По принципу работы данные функции полностью совпадают с одноимёнными функциями без префикса `Backtracking`, но поддерживают более широкий ассортимент регулярных выражений. Это происходит за счет того, что если конкретное регулярное выражение в полном объёме не поддерживается Hyperscan, то библиотека переключается в режим предварительной фильтрации (prefilter). В этом случае она отвечает не «да» или «нет», а «точно нет» или «может быть да». Ответы «может быть да» затем автоматически перепроверяются с помощью медленной, но более функциональной библиотеки [libpcre](https://www.pcre.org).
+
+Именно эти функции на данный момент вызываются в бинарных операторах [REGEXP](../../syntax/expressions.md#regexp) и [MATCH](../../syntax/expressions.md#match).
+
+## MultiGrep / MultiMatch {#multigrep}
+
+Библиотека Hyperscan предоставляет возможность за один проход по тексту проверить несколько регулярных выражений и получить по каждому из них отдельный ответ.
+
+Однако, если необходимо проверить совпадение строки с любым из перечисленных выражений (результаты объединялись бы через «или»), то эффективнее сделать одно регулярное выражение, объединив части с помощью оператора `|`, и использовать для поиска обычный `Grep` или `Match`.
+
+При вызове функций `MultiGrep`/`MultiMatch` регулярные выражения передаются по одному на строку с использованием [многострочных строковых литералов](../../syntax/expressions.md#named-nodes):
+
+**Пример**
+``` sql
+$multi_match = Hyperscan::MultiMatch(@@a.*
+.*x.*
+.*axa.*@@);
+
+SELECT
+ $multi_match("a") AS a,
+ $multi_match("axa") AS axa;
+
+/*
+- a: `(true, false, false)`
+- axa: `(true, true, true)`
+*/
+```
+
+## Capture и Replace {#capture}
+
+В библиотеке Hyperscan отсутствует развитая функциональность для подобных операций, так что `Hyperscan::Capture` и `Hyperscan::Replace` хоть и реализованы для единообразия, но для сколько-либо нетривиальных поисков и замен лучше использовать одноимённые функции из библиотеки Re2:
+
+* [Re2::Capture](re2.md#capture);
+* [Re2::Replace](re2.md#replace).
+
+
+## Пример использования.
+```sql
+$value = "xaaxaaXaa";
+
+$match = Hyperscan::Match("a.*");
+$grep = Hyperscan::Grep("axa");
+$insensitive_grep = Hyperscan::Grep("(?i)axaa$");
+$multi_match = Hyperscan::MultiMatch(@@a.*
+.*a.*
+.*a
+.*axa.*@@);
+
+$capture = Hyperscan::Capture(".*a{2}.*");
+$capture_many = Hyperscan::Capture(".*x(a+).*");
+$replace = Hyperscan::Replace("xa");
+
+SELECT
+ $match($value) AS match,
+ $grep($value) AS grep,
+ $insensitive_grep($value) AS insensitive_grep,
+ $multi_match($value) AS multi_match,
+ $multi_match($value).0 AS some_multi_match,
+ $capture($value) AS capture,
+ $capture_many($value) AS capture_many,
+ $replace($value, "b") AS replace
+;
+
+/*
+- match: false
+- grep: true
+- insensitive_grep: true
+- multi_match: (false, true, true, true)
+- some_multi_match: false
+- capture: "xaaa"
+- capture_many: "xaa"
+- replace: "babaXaa"
+*/
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/index.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/index.md
new file mode 100644
index 00000000000..7b4e51e9bd9
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/index.md
@@ -0,0 +1,4 @@
+{% include [x](_includes/index/intro.md) %}
+
+{% include [x](_includes/index/list.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/ip.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/ip.md
new file mode 100644
index 00000000000..98a824a33d3
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/ip.md
@@ -0,0 +1,27 @@
+# Ip
+В модуле `Ip` поддерживаются как IPv4, так и IPv6 адреса. По умолчанию они представляются в виде бинарных строк длиной 4 и 16 байт, соответственно.
+
+**Список функций**
+
+* ```Ip::FromString(String{Flags:AutoMap}) -> String?``` - из человекочитаемого представления в бинарное
+* ```Ip::ToString(String{Flags:AutoMap}) -> String?``` - из бинарного представления в человекочитаемое
+* ```Ip::IsIPv4(String?) -> Bool```
+* ```Ip::IsIPv6(String?) -> Bool```
+* ```Ip::IsEmbeddedIPv4(String?) -> Bool```
+* ```Ip::ConvertToIPv6(String{Flags:AutoMap}) -> String``` - IPv6 остается без изменений, а IPv4 становится embedded в IPv6
+* ```Ip::GetSubnet(String{Flags:AutoMap}, [Uint8?]) -> String``` - во втором аргументе размер подсети, по умолчанию 24 для IPv4 и 64 для IPv6
+
+**Примеры**
+
+```sql
+SELECT Ip::IsEmbeddedIPv4(
+ Ip::FromString("::ffff:77.75.155.3")
+); -- true
+
+SELECT
+ Ip::ToString(
+ Ip::GetSubnet(
+ Ip::FromString("213.180.193.3")
+ )
+ ); -- "213.180.193.0"
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/math.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/math.md
new file mode 100644
index 00000000000..f976a02b386
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/math.md
@@ -0,0 +1,135 @@
+# Math
+Набор обёрток вокруг функций из библиотеки libm, а также утилит Яндекс.
+
+## Константы {#constants}
+**Список функций**
+
+* ```Math::Pi() -> Double```
+* ```Math::E() -> Double```
+* ```Math::Eps() -> Double```
+
+**Примеры**
+
+```sql
+SELECT Math::Pi(); -- 3.141592654
+SELECT Math::E(); -- 2.718281828
+SELECT Math::Eps(); -- 2.220446049250313e-16
+```
+
+## (Double) -> Bool {#double-bool}
+
+**Список функций**
+
+* ```Math::IsInf(Double{Flags:AutoMap}) -> Bool```
+* ```Math::IsNaN(Double{Flags:AutoMap}) -> Bool```
+* ```Math::IsFinite(Double{Flags:AutoMap}) -> Bool```
+
+**Примеры**
+
+```sql
+SELECT Math::IsNaN(0.0/0.0); -- true
+SELECT Math::IsFinite(1.0/0.0); -- false
+```
+
+## (Double) -> Double {#double-double}
+
+**Список функций**
+
+* ```Math::Abs(Double{Flags:AutoMap}) -> Double```
+* ```Math::Acos(Double{Flags:AutoMap}) -> Double```
+* ```Math::Asin(Double{Flags:AutoMap}) -> Double```
+* ```Math::Asinh(Double{Flags:AutoMap}) -> Double```
+* ```Math::Atan(Double{Flags:AutoMap}) -> Double```
+* ```Math::Cbrt(Double{Flags:AutoMap}) -> Double```
+* ```Math::Ceil(Double{Flags:AutoMap}) -> Double```
+* ```Math::Cos(Double{Flags:AutoMap}) -> Double```
+* ```Math::Cosh(Double{Flags:AutoMap}) -> Double```
+* ```Math::Erf(Double{Flags:AutoMap}) -> Double```
+* ```Math::ErfInv(Double{Flags:AutoMap}) -> Double```
+* ```Math::ErfcInv(Double{Flags:AutoMap}) -> Double```
+* ```Math::Exp(Double{Flags:AutoMap}) -> Double```
+* ```Math::Exp2(Double{Flags:AutoMap}) -> Double```
+* ```Math::Fabs(Double{Flags:AutoMap}) -> Double```
+* ```Math::Floor(Double{Flags:AutoMap}) -> Double```
+* ```Math::Lgamma(Double{Flags:AutoMap}) -> Double```
+* ```Math::Rint(Double{Flags:AutoMap}) -> Double```
+* ```Math::Sigmoid(Double{Flags:AutoMap}) -> Double```
+* ```Math::Sin(Double{Flags:AutoMap}) -> Double```
+* ```Math::Sinh(Double{Flags:AutoMap}) -> Double```
+* ```Math::Sqrt(Double{Flags:AutoMap}) -> Double```
+* ```Math::Tan(Double{Flags:AutoMap}) -> Double```
+* ```Math::Tanh(Double{Flags:AutoMap}) -> Double```
+* ```Math::Tgamma(Double{Flags:AutoMap}) -> Double```
+* ```Math::Trunc(Double{Flags:AutoMap}) -> Double```
+* ```Math::Log(Double{Flags:AutoMap}) -> Double```
+* ```Math::Log2(Double{Flags:AutoMap}) -> Double```
+* ```Math::Log10(Double{Flags:AutoMap}) -> Double```
+
+**Примеры**
+
+```sql
+SELECT Math::Sqrt(256); -- 16
+SELECT Math::Trunc(1.2345); -- 1
+```
+
+## (Double, Double) -> Double {#doubledouble-double}
+
+**Список функций**
+
+* ```Math::Atan2(Double{Flags:AutoMap}, Double{Flags:AutoMap}) -> Double```
+* ```Math::Fmod(Double{Flags:AutoMap}, Double{Flags:AutoMap}) -> Double```
+* ```Math::Hypot(Double{Flags:AutoMap}, Double{Flags:AutoMap}) -> Double```
+* ```Math::Pow(Double{Flags:AutoMap}, Double{Flags:AutoMap}) -> Double```
+* ```Math::Remainder(Double{Flags:AutoMap}, Double{Flags:AutoMap}) -> Double```
+
+**Примеры**
+
+```sql
+SELECT Math::Atan2(1, 0); -- 1.570796327
+SELECT Math::Remainder(2.1, 2); -- 0.1
+```
+
+## (Double, Int32) -> Double {#doubleint32-double}
+
+**Список функций**
+
+* ```Math::Ldexp(Double{Flags:AutoMap}, Int32{Flags:AutoMap}) -> Double```
+* ```Math::Round(Double{Flags:AutoMap}, [Int32?]) -> Double``` - во втором аргументе указывается степень 10, до которой округляем (отрицательная для знаков после запятой и положительная для округления до десятков—тысяч—миллионов); по умолчанию 0
+
+**Примеры**
+
+```sql
+SELECT Math::Pow(2, 10); -- 1024
+SELECT Math::Round(1.2345, -2); -- 1.23
+```
+
+## (Double, Double, \[Double?\]) -> Bool {#doubledouble-bool}
+
+**Список функций**
+
+* ```Math::FuzzyEquals(Double{Flags:AutoMap}, Double{Flags:AutoMap}, [Double?]) -> Bool``` - сравнивает два Double на нахождение внутри окрестности, задаваемой третьим аргументом; по умолчанию 1.0e-13
+
+**Примеры**
+
+```sql
+SELECT Math::FuzzyEquals(1.01, 1.0, 0.05); -- true
+```
+
+## Функции взятия остатка
+
+**Список функций**
+
+* ```Math::Mod(Int64{Flags:AutoMap}, Int64) -> Int64?```
+* ```Math::Rem(Int64{Flags:AutoMap}, Int64) -> Int64?```
+
+Ведут себя аналогично встроенному оператору % в случае неотрицательных аргументов. Различия заметны при отрицательных аргументах:
+* Math::Mod сохраняет знак второго аргумента (делителя).
+* Math::Rem сохраняет знак первого аргумента (делимого).
+Функции возвращают null, если делитель равен нулю.
+
+**Примеры**
+
+```sql
+SELECT Math::Mod(-1, 7); -- 6
+SELECT Math::Rem(-1, 7); -- -1
+```
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/pcre.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/pcre.md
new file mode 100644
index 00000000000..f52f34c571d
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/pcre.md
@@ -0,0 +1,19 @@
+# Pcre
+
+Библиотека Pcre на данный момент является алиасом к [Hyperscan](hyperscan.md).
+
+{% if tech or feature_mapreduce %}
+Если вы завязываетесь на какие-либо особенности конкретного движка, реализующего регулярные выражения, то лучше использовать UDF с определённой библиотекой внутри, а Pcre рассматривать как текущий наиболее рекомендуемый вариант для простых проверок на соответствие, который может в будущем поменяться.
+{% endif %}
+
+На данный момент доступны:
+
+* [Hyperscan](hyperscan.md) <span style="color: gray;">(Intel)</span>
+* [Re2](re2.md) <span style="color: gray;">(Google)</span>
+* [Pire](pire.md) <span style="color: gray;">(Яндекс)</span>
+
+Hyperscan и Pire рассчитаны в первую очередь под Grep и Match. HyperScan внутри имеет несколько реализаций с использованием разных наборов процессорных инструкций, среди которых автоматически выбирается нужная в соответствии с текущим процессором. Pire также известна своей отличной производительностью и если вам это важно, то стоит померить на своих данных и регулярных выражениях и её, но с 2011-2013 года эта библиотека практически не развивается и как намекает название («i» расшифровывается как incompatible), возможно потребуется адаптировать сами выражения.
+
+Основной плюс библиотеки Re2 — развитый функционал по Capture и Replace, если вам нужны эти функции, то рекомендуется пользоваться именно ей.
+
+В Hyperscan также доступны отдельные функции с backtracking (возможность сослаться на предыдущую найденную часть строки), которые реализованы через гибридное использование двух библиотек Hyperscan и libpcre.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/pire.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/pire.md
new file mode 100644
index 00000000000..7bfb3536b4f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/pire.md
@@ -0,0 +1,129 @@
+# Pire
+
+**Список функций**
+
+* ```Pire::Grep(String) -> (String?) -> Bool```
+* ```Pire::Match(String) -> (String?) -> Bool```
+* ```Pire::MultiGrep(String) -> (String?) -> Tuple<Bool, Bool, ...>```
+* ```Pire::MultiMatch(String) -> (String?) -> Tuple<Bool, Bool, ...>```
+* ```Pire::Capture(String) -> (String?) -> String?```
+* ```Pire::Replace(String) -> (String?, String) -> String?```
+
+Одной из опций для поиска по регулярным выражениям в YQL является библиотека [Pire](https://github.com/yandex/pire) (Perl Incompatible Regular Expressions). Это разработанная в Яндексе очень быстрая библиотека регулярных выражений: на нижнем уровне она просматривает входную строку один раз, подряд, без откатов, и тратит (на x86 и x86_64) по 5 инструкций на символ.
+
+Скорость работы достигается за счет некоторых разумных ограничений:
+
+* Библиотека Pire ориентирована прежде всего на проверку на совпадение строки с регулярным выражением (Match).
+* Возможность вернуть совпавшую подстроку тоже поддерживается (Capture), но с ограничениями (возвращает совпадение только с одной группой).
+
+По умолчанию все функции работают в однобайтовом режиме, но если регулярное выражение является валидной UTF-8 строкой, но не является валидной ASCII строкой, — автоматически включается режим UTF-8.
+
+Чтобы включить Unicode-режим, можно вставить в выражение один символ за пределами ASCII с оператором `?`, например `\\w+я?`.
+
+## Синтаксис вызова {#call-syntax}
+
+Чтобы избежать компиляции регулярного выражения на каждой строке таблицы, необходимо обернуть вызов функции в [именованное выражение](../../syntax/expressions.md#named-nodes):
+
+```sql
+$re = Pire::Grep("\\d+"); -- создаем вызываемое значение для проверки конкретного регулярного выражения
+SELECT * FROM table WHERE $re(key); -- используем его для фильтрации таблицы
+```
+
+{% note alert %}
+
+При экранировании спецсимволов в регулярном выражении нужен второй слеш, так как все стандартные строковые литералы в SQL могут принимать С-escaped строки, а последовательность `\d` не является валидной последовательностью, и даже если бы являлась — не приводила бы к ожидаемому эффекту поиска чисел.
+
+{% endnote %}
+
+Есть возможность отключить чувствительность к регистру (то есть включить case-insensitive режим), указав в начале регулярного выражения флаг `(?i)`.
+
+**Примеры**
+
+```sql
+$value = "xaaxaaxaa";
+$match = Pire::Match("a.*");
+$grep = Pire::Grep("axa");
+$insensitive_grep = Pire::Grep("(?i)axa");
+$multi_match = Pire::MultiMatch(@@a.*
+.*a.*
+.*a
+.*axa.*@@);
+$capture = Pire::Capture(".*x(a).*");
+$capture_many = Pire::Capture(".*x(a+).*");
+$replace = Pire::Replace(".*x(a).*");
+
+SELECT
+ $match($value) AS match,
+ $grep($value) AS grep,
+ $insensitive_grep($value) AS insensitive_grep,
+ $multi_match($value) AS multi_match,
+ $multi_match($value).0 AS some_multi_match,
+ $capture($value) AS capture,
+ $capture_many($value) AS capture_many,
+ $replace($value, "b") AS replace;
+
+/*
+- match: `false`
+- grep: `true`
+- insensitive_grep: `true`
+- multi_match: `(false, true, true, true)`
+- some_multi_match: `false`
+- capture: `"a"`
+- capture_many: `"aa"`
+- replace: `"xaaxaaxba"`
+*/
+```
+
+## Grep {#grep}
+
+Проверяет совпадение регулярного выражения с **частью строки** (произвольной подстрокой).
+
+## Match {#match}
+
+Проверяет совпадение регулярного выражения **со строкой целиком**.
+Чтобы получить результат, аналогичный `Grep` (где учитывается совпадение с подстрокой), нужно обернуть регулярное выражение с обоих сторон в `.*`, например `.*foo.*` вместо `foo`.
+
+## MultiGrep / MultiMatch {#multigrep}
+
+Библиотека Pire предоставляет возможность за один проход по тексту проверить несколько регулярных выражений и получить по каждому из них отдельный ответ.
+С помощью функций MultiGrep/MultiMatch можно оптимизировать скорость выполнения запроса, но это нужно делать осмотрительно, поскольку размер используемого для проверки конечного автомата растет экспоненциально с числом регулярных выражений:
+
+* Если вас интересует совпадение строки с любым из перечисленных выражений (результаты объединяются через «или»), то намного эффективнее сделать одно регулярное выражение, объединив части с помощью оператора `|`, и использовать для поиска обычный Grep или Match.
+* В библиотеке Pire установлен лимит на размер конечного автомата (в YQL используется значение этого лимита, установленное по умолчанию в библиотеке). Если лимит превышен, при запуске запроса вернется ошибка `Failed to glue up regexes, probably the finite state machine appeared to be too large`.
+При вызове функций MultiGrep/MultiMatch регулярные выражения передаются по одному на строку с использованием [многострочных строковых литералов](../../syntax/expressions.md#multiline-string-literals):
+
+**Примеры**
+
+```sql
+$multi_match = Pire::MultiMatch(@@a.*
+.*x.*
+.*axa.*@@);
+
+SELECT
+ $multi_match("a") AS a,
+ $multi_match("axa") AS axa;
+
+/*
+- a: `(true, false, false)`
+- axa: `(true, true, true)`
+*/
+```
+
+## Capture {#capture}
+
+При совпадении строки с указанным регулярным выражением возвращает подстроку, совпавшую с группой, отмеченной в регулярном выражении круглыми скобками.
+Capture работает НЕ в жадном режиме, то есть возвращается самая короткая подстрока из возможных.
+
+{% note alert %}
+
+В выражении должна быть ровно **одна** группа, обозначенная круглыми скобками. В случае отсутствия совпадения возвращается `NULL` (пустой Optional).
+
+{% endnote %}
+
+Если описанные выше ограничения и особенности по каким-либо причинам выглядят неприемлемыми, рекомендуется рассмотреть возможность использования [Re2::Capture](re2.md#capture).
+
+## Replace {#replace}
+
+В библиотеке Pire отсутствует функция замены по регулярному выражению. Функция `Pire::Replace` в YQL представляет собой упрощенную эмуляцию, реализованную с помощью `Capture`. Может работать некорректно, если найденная подстрока встречается в исходной более одного раза.
+
+Как правило, лучше воспользоваться [Re2::Replace](re2.md#replace) вместо неё.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/re2.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/re2.md
new file mode 100644
index 00000000000..1f73ae159c0
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/re2.md
@@ -0,0 +1,120 @@
+# Re2
+
+**Список функций**
+
+* ```Re2::Grep(String) -> (String?) -> Bool```
+* ```Re2::Match(String) -> (String?) -> Bool```
+* ```Re2::Capture(String) -> (String?) -> Struct<_1:String?,foo:String?,...>```
+* ```Re2::FindAndConsume(String) -> (String?) -> List<String>```
+* ```Re2::Replace(String) -> (String?, String) -> String?```
+* ```Re2::Count(String) -> (String?) -> Uint32```
+* ```Re2::Options([CaseSensitive:Bool?,DotNl:Bool?,Literal:Bool?,LogErrors:Bool?,LongestMatch:Bool?,MaxMem:Uint64?,NeverCapture:Bool?,NeverNl:Bool?,OneLine:Bool?,PerlClasses:Bool?,PosixSyntax:Bool?,Utf8:Bool?,WordBoundary:Bool?]) -> Struct<CaseSensitive:Bool,DotNl:Bool,Literal:Bool,LogErrors:Bool,LongestMatch:Bool,MaxMem:Uint64,NeverCapture:Bool,NeverNl:Bool,OneLine:Bool,PerlClasses:Bool,PosixSyntax:Bool,Utf8:Bool,WordBoundary:Bool>```
+
+В силу ограничений библиотеки Pire, связанных с оптимизацией для эффективной проверки строк на соответствие регулярным выражениям, бывают ситуации, когда решить задачу с помощью [Pire](pire.md) неоправданно сложно или невозможно. Для таких ситуаций мы добавили ещё один модуль для работы с регулярными выражениями на основе [google::RE2](https://github.com/google/re2), где предоставляется более широкий ассортимент возможностей ([см. официальную документацию](https://github.com/google/re2/wiki/Syntax)).
+
+По умолчанию UTF-8 режим включается автоматически, если регулярное выражение является валидной строкой в кодировке UTF-8, но не является валидной ASCII-строкой. Вручную настройками библиотеки re2 можно управлять с помощью передачи результата функции `Re2::Options` вторым аргументом другим функциям модуля, рядом с регулярным выражением.
+
+{% note warning %}
+
+Все обратные слеши в регулярных выражениях (если они записаны в строке с кавычками) нужно удваивать, так как стандартные строковые литералы в SQL рассматриваются как С-escaped строки. Также можно записывать регулярное выражение в форме raw строки `@@regexp@@` — в этом случае удвоение слешей не требуется.
+
+{% endnote %}
+
+**Примеры**
+
+```sql
+$value = "xaaxaaxaa";
+$options = Re2::Options(false AS CaseSensitive);
+$match = Re2::Match("[ax]+\\d");
+$grep = Re2::Grep("a.*");
+$capture = Re2::Capture(".*(?P<foo>xa?)(a{2,}).*");
+$replace = Re2::Replace("x(a+)x");
+$count = Re2::Count("a", $options);
+
+SELECT
+ $match($value) AS match,
+ $grep($value) AS grep,
+ $capture($value) AS capture,
+ $capture($value)._1 AS capture_member,
+ $replace($value, "b\\1z") AS replace,
+ $count($value) AS count;
+
+/*
+- match: `false`
+- grep: `true`
+- capture: `(_0: 'xaaxaaxaa', _1: 'aa', foo: 'x')`
+- capture_member: `"aa"`
+- replace: `"baazaaxaa"`
+- count:: `6`
+*/
+```
+
+## Re2::Grep / Re2::Match {#match}
+
+Если вынести за скобки детали реализации и синтаксиса регулярных выражений, эти функции полностью аналогичны [аналогичным функциям](pire.md#match) из модулей Pire. При прочих равных и отсутствии каких-либо специфических предпочтений мы рекомендуем пользоваться `Pire::Grep / Pire::Match`.
+
+## Re2::Capture {#capture}
+
+В отличие от [Pire::Capture](pire.md#capture) в `Re2::Capture` поддерживаются множественные и именованные группы захвата (capturing groups).
+Тип результата: структура с полями типа `String?`.
+
+* Каждое поле соответствует группе захвата с соответствующим именем.
+* Для неименованных групп генерируются имена вида: `_1`, `_2` и т.д.
+* В результат всегда включается поле `_0`, в котором доступна вся совпавшая с регулярным выражением подстрока.
+
+Подробнее про работу со структурами в YQL см. в [разделе про контейнеры](../../types/containers.md).
+
+## Re2::FindAndConsume {#findandconsume}
+
+Ищет все вхождения регулярного выражения в переданный текст и возвращает список значений, соответствующих обрамленной в круглые скобки части регулярного выражения для каждого вхождения.
+
+## Re2::Replace {#replace}
+
+Работает следующим образом:
+
+* Во входной строке (первый аргумент) все непересекающиеся подстроки, совпавшие с регулярным выражением, заменяются на указанную строку (второй аргумент).
+* В строке с заменой можно использовать содержимое групп захвата (capturing groups) из регулярного выражения с помощью ссылок вида: `\\1`, `\\2` и т.д. Ссылка `\\0` обозначает всю совпавшую с регулярным выражением подстроку.
+
+## Re2::Count {#count}
+
+Возвращает количество совпавших с регулярным выражением непересекающихся подстрок во входной строке.
+
+## Re2::Options {#options}
+
+Пояснения к параметрам Re2::Options из официального [репозитория](https://github.com/google/re2/blob/main/re2/re2.h#L595-L617)
+
+| Параметр | По умолчанию | Комментарий |
+|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-------------------------------------------------------------------------------------|
+| CaseSensitive:Bool? | true | match is case-sensitive (regexp can override with (?i) unless in posix_syntax mode) |
+| DotNl:Bool? | false | let `.` match `\n` (default ) |
+| Literal:Bool? | false | interpret string as literal, not regexp |
+| LogErrors:Bool? | true | log syntax and execution errors to ERROR |
+| LongestMatch:Bool? | false | search for longest match, not first match |
+| MaxMem:Uint64? | - | (see below) approx. max memory footprint of RE2 |
+| NeverCapture:Bool? | false | parse all parens as non-capturing |
+| NeverNl:Bool? | false | never match \n, even if it is in regexp |
+| PosixSyntax:Bool? | false | restrict regexps to POSIX egrep syntax |
+| Utf8:Bool? | true | text and pattern are UTF-8; otherwise Latin-1 |
+| The following options are only consulted when PosixSyntax == true. <bt>When PosixSyntax == false, these features are always enabled and cannot be turned off; to perform multi-line matching in that case, begin the regexp with (?m). ||
+| PerlClasses:Bool? | false | allow Perl's \d \s \w \D \S \W |
+| WordBoundary:Bool? | false | allow Perl's \b \B (word boundary and not) |
+| OneLine:Bool? | false | ^ and $ only match beginning and end of text |
+
+Не рекомендуется Re2::Options использовать в коде. Большинство параметров можно заменить на флаги регулярного выражения.
+
+**Пример использования флагов**
+```sql
+$value = "Foo bar FOO"u;
+-- включить режим без учета регистра
+$capture = Re2::Capture(@@(?i)(foo)@@);
+
+SELECT
+ $capture($value) AS capture;
+
+$capture = Re2::Capture(@@(?i)(?P<vasya>FOO).*(?P<banan>bar)@@);
+
+SELECT
+ $capture($value) AS capture;
+```
+
+В обоих случаях слово ВАСЯ будет найдено. Применение raw строки @@regexp@@ позволяет не удваивать слеши.
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/string.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/string.md
new file mode 100644
index 00000000000..b5f49d258a8
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/string.md
@@ -0,0 +1,2 @@
+
+{% include [x](_includes/string.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/toc_base.yaml b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/toc_base.yaml
new file mode 100644
index 00000000000..6cd9dbcbd2b
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/toc_base.yaml
@@ -0,0 +1,16 @@
+items:
+- name: Обзор
+ href: index.md
+- { name: Hyperscan, href: hyperscan.md }
+- { name: Pcre, href: pcre.md }
+- { name: Pire, href: pire.md }
+- { name: Re2, href: re2.md }
+- { name: String, href: string.md }
+- { name: Unicode, href: unicode.md }
+- { name: DateTime, href: datetime.md }
+- { name: Url, href: url.md }
+- { name: Ip, href: ip.md }
+- { name: Yson, href: yson.md }
+- { name: Digest, href: digest.md }
+- { name: Math, href: math.md }
+- { name: Histogram, href: histogram.md }
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/toc_i.yaml b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/toc_i.yaml
new file mode 100644
index 00000000000..28325999d2f
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/toc_i.yaml
@@ -0,0 +1,2 @@
+items:
+- include: { mode: link, path: toc_base.yaml } \ No newline at end of file
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/unicode.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/unicode.md
new file mode 100644
index 00000000000..60a2d0fc41c
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/unicode.md
@@ -0,0 +1,3 @@
+
+{% include [x](_includes/unicode.md) %}
+
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/url.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/url.md
new file mode 100644
index 00000000000..f7ed9339654
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/url.md
@@ -0,0 +1,2 @@
+
+{% include [url.md](_includes/url.md) %}
diff --git a/ydb/docs/ru/core/yql/reference/yql-core/udf/list/yson.md b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/yson.md
new file mode 100644
index 00000000000..568aa59fa6b
--- /dev/null
+++ b/ydb/docs/ru/core/yql/reference/yql-core/udf/list/yson.md
@@ -0,0 +1,273 @@
+# Yson
+
+{% include [_includes/yson/intro_header.md](_includes/yson/intro_header.md) %}
+
+* Сходства с JSON:
+ * не имеет строгой схемы;
+ * помимо простых типов данных поддерживает словари и списки в произвольных комбинациях.
+* Некоторые отличия от JSON:
+ * Помимо текстового представления имеет и бинарное;
+ * В текстовом представлении вместо запятых — точки с запятой, а вместо двоеточий — равно;
+* Поддерживается концепция «атрибутов», то есть именованных свойств, которые могут быть присвоены узлу в дереве.
+
+Особенности реализации и функциональность модуля:
+
+* Наравне с YSON данный модуль поддерживает и стандартный JSON, что несколько расширяет область его применения.
+* Работает с DOM представлением YSON в памяти, которое в терминах YQL передается между функциями как «ресурс» (см. [описание специальных типов данных](../../types/special.md)). Большинство функций модуля имеют семантику запроса на выполнение указанной операции с ресурсом и возвращают пустой [optional](../../types/optional.md), если операция не удалась из-за несоответствия фактического типа данных ожидаемому.
+* Предоставляет несколько основных классов функций (полный список и подробное описание функций см. ниже):
+ * `Yson::Parse***` — получение ресурса с DOM-объектом из сериализованных данных, все дальнейшие операции выполняются уже над полученным ресурсом;
+ * `Yson::From` — получение ресурса с DOM-объектом из простых типов данных YQL или контейнеров (списков или словарей);
+ * `Yson::ConvertTo***` — преобразовать ресурс к [простым типам данных](../../types/primitive.md) или [контейнерам](../../types/containers.md);
+ * `Yson::Lookup***` — получение одного элемента списка или словаря с опциональным преобразованием в нужный тип данных;
+ * `Yson::YPath***` — получение одного элемента дерева документа по указанному относительному пути с опциональным преобразованием в нужный тип данных;
+ * `Yson::Serialize***` — получить из ресурса копию его данных, сериализованную в одном из форматов;
+* Для удобства при передаче сериализованного Yson и Json в функции, ожидающие на входе ресурс с DOM-объектом, неявное преобразование через `Yson::Parse` или `Yson::ParseJson` происходит автоматически. Также в SQL синтаксисе оператор точки или квадратных скобок автоматически добавляет вызов `Yson::Lookup`. Для сериализации ресурса по-прежнему нужно вызывать `Yson::ConvertTo***` или `Yson::Serialize***`. Таким образом, например, получение элемента "foo" словаря из колонки mycolumn типа Yson в виде строки может выглядеть так: `SELECT Yson::ConvertToString(mycolumn["foo"]) FROM mytable;` или `SELECT Yson::ConvertToString(mycolumn.foo) FROM mytable;`. В варианте с точкой можно экранировать спецсимволы по [общим правилам для индентификаторов](../../syntax/expressions.md#escape).
+
+Функции модуля стоит рассматривать как «кубики», из которых можно собирать разные конструкции, например:
+
+* `Yson::Parse*** -> Yson::Serialize***` — конвертация из одного формата в другой;
+* `Yson::Parse*** -> Yson::Lookup -> Yson::Serialize***` — извлечение значения указанного поддерева в исходном дереве YSON;
+* `Yson::Parse*** -> Yson::ConvertToList -> ListMap -> Yson::Lookup***` — извлечение элементов по ключу из YSON списка.
+
+{% include [_includes/yson/intro_footer.md](_includes/yson/intro_footer.md) %}
+
+**Примеры**
+
+``` yql
+$node = Json(@@
+ {"abc": {"def": 123, "ghi": "привет"}}
+@@);
+SELECT Yson::SerializeText($node.abc) AS `yson`;
+-- {"def"=123;"ghi"="\xD0\xBF\xD1\x80\xD0\xB8\xD0\xB2\xD0\xB5\xD1\x82"}
+```
+
+``` yql
+$node = Yson(@@
+ <a=z;x=y>[
+ {abc=123; def=456};
+ {abc=234; xyz=789};
+ ]
+@@);
+$attrs = Yson::YPath($node, "/@");
+
+SELECT
+ ListMap(Yson::ConvertToList($node), ($x) -> { return Yson::LookupInt64($x, "abc") }) AS abcs,
+ Yson::ConvertToStringDict($attrs) AS attrs,
+ Yson::SerializePretty(Yson::Lookup($node, "7", Yson::Options(false AS Strict))) AS miss;
+
+/*
+- abcs: `[123; 234]`
+- attrs: `{"a"="z";"x"="y"}`
+- miss: `NULL`
+*/
+```
+
+## Yson::Parse... {#ysonparse}
+
+``` yql
+Yson::Parse(Yson{Flags:AutoMap}) -> Resource<'Yson2.Node'>
+Yson::ParseJson(Json{Flags:AutoMap}) -> Resource<'Yson2.Node'>
+Yson::ParseJsonDecodeUtf8(Json{Flags:AutoMap}) -> Resource<'Yson2.Node'>
+
+Yson::Parse(String{Flags:AutoMap}) -> Resource<'Yson2.Node'>? -- принимает YSON в любом формате
+Yson::ParseJson(String{Flags:AutoMap}) -> Resource<'Yson2.Node'>?
+Yson::ParseJsonDecodeUtf8(String{Flags:AutoMap}) -> Resource<'Yson2.Node'>?
+```
+
+Результат всех трёх функций является несериализуемым: его можно только передать на вход другой функции из библиотеки Yson, но нельзя сохранить в таблицу или вернуть на клиент в результате операции — попытка так сделать приведет к ошибке типизации. Также запрещено возвращать его за пределы [подзапросов](../../syntax/select.md): если это требуется, то надо вызвать [Yson::Serialize](#ysonserialize), а оптимизатор уберёт лишнюю сериализию и десериализацию, если материализация в конечном счёте не потребуется.
+
+{% note info "Примечание" %}
+
+Функция `Yson::ParseJsonDecodeUtf8` ожидает, что символы, выходящие за пределы ASCII, должны быть дополнительно заэкранированы.
+
+{% endnote %}
+
+
+## Yson::From {#ysonfrom}
+``` yql
+Yson::From(T) -> Resource<'Yson2.Node'>
+```
+
+`Yson::From` является полиморфной функцией, преобразующей в Yson ресурс большинство примитивных типов данных и контейнеров (списки, словари, кортежи, структуры и т.п.). Тип исходного объекта должен быть совместим с Yson. Например, в ключах словарей допустимы только типы `String` или `Utf8`, а вот `String?` или `Utf8?` уже нет.
+
+**Пример**
+
+```sql
+SELECT Yson::Serialize(Yson::From(TableRow())) FROM table1;
+```
+
+## Yson::WithAttributes
+``` yql
+Yson::WithAttributes(Resource<'Yson2.Node'>{Flags:AutoMap}, Resource<'Yson2.Node'>{Flags:AutoMap}) -> Resource<'Yson2.Node'>?
+```
+Добавляет к узлу Yson (первый аргумент) атрибуты (второй аргумент). Атрибуты должны представлять из себя узел map.
+
+## Yson::Equals
+
+``` yql
+Yson::Equals(Resource<'Yson2.Node'>{Flags:AutoMap}, Resource<'Yson2.Node'>{Flags:AutoMap}) -> Bool
+```
+Проверка деревьев в памяти на равенство, толерантная к исходному формату сериализации и порядку перечисления ключей в словарях.
+
+## Yson::GetHash
+``` yql
+Yson::GetHash(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Uint64
+```
+Вычисление 64-битного хэша от дерева объектов.
+
+## Yson::Is...
+``` yql
+Yson::IsEntity(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsString(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsDouble(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsUint64(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsInt64(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsBool(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsList(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+Yson::IsDict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> bool
+```
+Проверка, что текущий узел имеет соответствующий тип. Entity это `#`.
+
+## Yson::GetLength
+``` yql
+Yson::GetLength(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Uint64?
+```
+Получение числа элементов в списке или словаре.
+
+## Yson::ConvertTo... {#ysonconvertto}
+``` yql
+Yson::ConvertTo(Resource<'Yson2.Node'>{Flags:AutoMap}, Type<T>) -> T
+Yson::ConvertToBool(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Bool?
+Yson::ConvertToInt64(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Int64?
+Yson::ConvertToUint64(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Uint64?
+Yson::ConvertToDouble(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Double?
+Yson::ConvertToString(Resource<'Yson2.Node'>{Flags:AutoMap}) -> String?
+Yson::ConvertToList(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<Resource<'Yson2.Node'>>
+Yson::ConvertToBoolList(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<Bool>
+Yson::ConvertToInt64List(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<Int64>
+Yson::ConvertToUint64List(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<Uint64>
+Yson::ConvertToDoubleList(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<Double>
+Yson::ConvertToStringList(Resource<'Yson2.Node'>{Flags:AutoMap}) -> List<String>
+Yson::ConvertToDict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Resource<'Yson2.Node'>>
+Yson::ConvertToBoolDict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Bool>
+Yson::ConvertToInt64Dict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Int64>
+Yson::ConvertToUint64Dict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Uint64>
+Yson::ConvertToDoubleDict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Double>
+Yson::ConvertToStringDict(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,String>
+```
+
+{% note warning "Внимание" %}
+
+Данные функции по умолчанию не делают неявного приведения типов, то есть значение в аргументе должно в точности соответствовать вызываемой функции.
+
+{% endnote %}
+
+`Yson::ConvertTo` является полиморфной функцией, преобразующей Yson ресурс в указанный во втором аргументе тип данных с поддержкой вложенных контейнеров (списки, словари, кортежи, структуры и т.п.).
+
+**Пример**
+
+```sql
+$data = Yson(@@{
+ "name" = "Anya";
+ "age" = 15u;
+ "params" = {
+ "ip" = "95.106.17.32";
+ "last_time_on_site" = 0.5;
+ "region" = 213;
+ "user_agent" = "Mozilla/5.0"
+ }
+}@@);
+SELECT Yson::ConvertTo($data,
+ Struct<
+ name: String,
+ age: Uint32,
+ params: Dict<String,Yson>
+ >
+);
+```
+
+## Yson::Contains {#ysoncontains}
+``` yql
+Yson::Contains(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Bool?
+```
+Проверяет наличие ключа в словаре. Если тип объекта map, то ищем среди ключей.
+Если тип объекта список, то ключ должен быть десятичным числом - индексом в списке.
+
+
+## Yson::Lookup... {#ysonlookup}
+``` yql
+Yson::Lookup(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Resource<'Yson2.Node'>?
+Yson::LookupBool(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Bool?
+Yson::LookupInt64(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Int64?
+Yson::LookupUint64(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Uint64?
+Yson::LookupDouble(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Double?
+Yson::LookupString(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> String?
+Yson::LookupDict(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Dict<String,Resource<'Yson2.Node'>>?
+Yson::LookupList(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> List<Resource<'Yson2.Node'>>?
+```
+Перечисленные выше функции представляют собой краткую форму записи для типичного сценария использования: `Yson::YPath` — переход в словарь на один уровень с последующим извлечением значения — `Yson::ConvertTo***`. Второй аргумент для всех перечисленных функций — имя ключа в словаре (в отличие от YPath, без префикса `/`) или индекс в списке (например, `7`). Упрощают запрос и дают небольшой выигрыш в скорости работы.
+
+
+## Yson::YPath {#ysonypath}
+``` yql
+Yson::YPath(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Resource<'Yson2.Node'>?
+Yson::YPathBool(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Bool?
+Yson::YPathInt64(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Int64?
+Yson::YPathUint64(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Uint64?
+Yson::YPathDouble(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Double?
+Yson::YPathString(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> String?
+Yson::YPathDict(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> Dict<String,Resource<'Yson2.Node'>>?
+Yson::YPathList(Resource<'Yson2.Node'>{Flags:AutoMap}, String) -> List<Resource<'Yson2.Node'>>?
+```
+Позволяет по входному ресурсу и пути на языке YPath получить ресурс, указывающий на соответствующую пути часть исходного ресурса.
+
+{% include [_includes/yson/ypath_overlay.md](_includes/yson/ypath_overlay.md) %}
+
+## Yson::Attributes {#ysonattributes}
+``` yql
+Yson::Attributes(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Dict<String,Resource<'Yson2.Node'>>
+```
+Получение всех атрибутов узла в виде словаря.
+
+## Yson::Serialize... {#ysonserialize}
+``` yql
+Yson::Serialize(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Yson -- бинарное представление
+Yson::SerializeText(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Yson
+Yson::SerializePretty(Resource<'Yson2.Node'>{Flags:AutoMap}) -> Yson -- чтобы увидеть именно текстовый результат, можно обернуть его в ToBytes(...)
+```
+
+## Yson::SerializeJson {#ysonserializejson}
+```yql
+Yson::SerializeJson(Resource<'Yson2.Node'>{Flags:AutoMap}, [Resource<'Yson2.Options'>?, SkipMapEntity:Bool?, EncodeUtf8:Bool?]) -> Json?
+```
+
+* `SkipMapEntity` отвечает за сериализацию значений в словарях, имеющих значение `#`. На значение атрибутов флаг не влияет. По умолчанию `false`.
+* `EncodeUtf8` отвечает за экранирование символов, выходящих за пределы ASCII. По умолчанию `false`.
+
+Типы данных `Yson` и `Json`, возвращаемые функциями сериализации, представляет собой частный случай строки, про которую известно, что в ней находятся данные в соответствующем формате (Yson/Json).
+
+## Yson::Options {#ysonoptions}
+``` yql
+Yson::Options([AutoConvert:Bool?, Strict:Bool?]) -> Resource<'Yson2.Options'>
+```
+Передаётся последним опциональным аргументом (который для краткости не указан) в методы `Parse...`, `ConvertTo...`, `Contains`, `Lookup...` и `YPath...`, которые принимают результат вызова `Yson::Options`. По умолчанию все поля `Yson::Options` выключены (false), а при включении (true) модифицируют поведение следующим образом:
+
+* **AutoConvert** — если переданное в Yson значение не в точности соответствует типу данных результата, то значение будет по возможности сконвертировано. Например, `Yson::ConvertToInt64` в этом режиме будет делать Int64 даже из чисел типа Double.
+* **Strict** — по умолчанию все функции из библиотеки Yson возвращают ошибку в случае проблем в ходе выполнения запроса (например, попытка парсинга строки не являющейся Yson/Json, или попытка поиска по ключу в скалярном типе, или запрошено преобразование в несовместимый тип данных, и т.п.), а если отключить строгий режим, то вместо ошибки в большинстве случаев будет возвращаться `NULL`. При преобразовании в словарь или список (`ConvertTo<Type>Dict` или `ConvertTo<Type>List`) плохие элементы будут выброшены из полученной коллекции.
+
+**Пример:**
+``` yql
+$yson = @@{y = true; x = 5.5}@@y;
+SELECT Yson::LookupBool($yson, "z"); --- null
+SELECT Yson::LookupBool($yson, "y"); --- true
+
+SELECT Yson::LookupInt64($yson, "x"); --- Ошибка
+SELECT Yson::LookupInt64($yson, "x", Yson::Options(false as Strict)); --- null
+SELECT Yson::LookupInt64($yson, "x", Yson::Options(true as AutoConvert)); --- 5
+
+SELECT Yson::ConvertToBoolDict($yson); --- Ошибка
+SELECT Yson::ConvertToBoolDict($yson, Yson::Options(false as Strict)); --- { "y": true }
+SELECT Yson::ConvertToDoubleDict($yson, Yson::Options(false as Strict)); --- { "x": 5.5 }
+```
+
+Если во всём запросе требуется применять одинаковые значения настроек библиотеки Yson, то удобнее воспользоваться [PRAGMA yson.AutoConvert;](../../syntax/pragma.md#yson.autoconvert) и/или [PRAGMA yson.Strict;](../../syntax/pragma.md#yson.strict). Также эти `PRAGMA` являются единственным способом повлиять на неявные вызовы библиотеки Yson, которые возникают при работе с типами данных Yson/Json.