Skip to content

Mode B as a SQL-compatible grammar: SQL forms in every position, casts, FILTER, quoted identifiers, NULL ordering - #509

Open
ZmeiGorynych wants to merge 18 commits into
mainfrom
egor/dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms
Open

ZmeiGorynych wants to merge 18 commits into
mainfrom
egor/dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms

Conversation

@ZmeiGorynych

@ZmeiGorynych ZmeiGorynych commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Closes DEV-2101.

What this does

Mode B (measures, dimensions, filters, order targets, saved measure formulas) used to be parsed as Python with a stack of text pre-passes that rewrote SQL spellings into Python. It is now one SQL-compatible grammar (slayer/core/syntax.py, built on pyparsing's infix_notation), shared by every position, so whatever is valid in a filter is valid in a measure, a dimension or an order target, and only typing decides whether it makes sense there. The importers (dbt, Cube, OSI) use the same parser; the old parse_formula / FieldSpec parser is gone.

New in every Mode-B position

  • CAST(x AS type) / x::type: the database's own cast of the type you write (DECIMAL(10,2) stays DECIMAL(10, 2)).
  • TRY_CAST(x AS type): NULL for input the cast cannot convert, on every dialect (Postgres < 16 or unknown version gets a plain CAST).
  • FILTER (WHERE c) on any aggregation: count(*) FILTER (WHERE status = 'paid'), last(amount) FILTER (WHERE amount > 0).
  • BETWEEN, IS [NOT] DISTINCT FROM, IS [NOT] TRUE / FALSE, ILIKE, ||, EXTRACT, POSITION … IN …, SUBSTRING … FROM … FOR …, CASE anywhere.
  • INTERVAL '7 days' / INTERVAL '7' DAY / INTERVAL 7 DAY, DATE '…' / TIMESTAMP '…', CURRENT_DATE / CURRENT_TIMESTAMP.
  • Double-quoted identifiers: sum("order total"), customers."Region".
  • Order items take "nulls": "first" | "last", honoured on every dialect including SQL Server.
  • Order expressions resolve measure aliases like filters do, and a grouped query ordered by an off-grain row expression sorts groups by its MIN (asc) / MAX (desc), as a bare column already did.
{
  "source_model": "orders",
  "dimensions": ["status"],
  "measures": [
    {"formula": "sum(amount)", "name": "rev"},
    {"formula": "count(*) FILTER (WHERE amount BETWEEN 10 AND 50)", "name": "mid"},
    {"formula": "sum(TRY_CAST(code AS INT))", "name": "codes"}
  ],
  "filters": ["created_at >= DATE '2024-01-01' AND customer_name <> 'O''Brien'"],
  "order": [{"column": "rev / mid", "direction": "desc", "nulls": "last"}]
}

Breaking changes

  • A double-quoted token is an identifier, never a string: write status = 'paid'. Stored models, saved queries and memories are upgraded on load (SlayerModel 16, SlayerQuery 7, Memory 5); queries sent by clients are not.
  • Strings follow SQL: '' for an embedded quote, backslash is an ordinary character.
  • a | b (use ||) and a // b (use div(a, b) / floor(a / b)) are rejected with a hint.
  • {variable} placeholders bind literal values only: a placeholder in a name position (sum({col}), customers.{c}, partition_by={x}) is rejected, so no value can change an expression's structure.
  • slayer.core.formula is removed; use slayer.core.syntax.parse_expr.
  • name = value inside a scalar call is a comparison (iif(status = 'paid', 1, 0)); in aggregations and transforms it stays a keyword argument. Errors on the wrong spelling say which reading applied.

Notes for review

  • Parsing is cached per text; a cold parse costs a few hundred µs to a few ms, so a typical cold query is ~1.9 ms slower than on main (packrat was measured slower and is off).
  • % / mod over a non-integer still fails on Postgres and SQL Server, as on main; that is deferred to DEV-2120.
  • On SQL Server, Oracle and Redshift the hand-built null-safe equality is now two-valued ((a = b AND a IS NOT NULL AND b IS NOT NULL) OR (a IS NULL AND b IS NULL)), so IS DISTINCT FROM keeps rows where one side is NULL; the grain join-backs use the same form, hence the T-SQL / Oracle / Redshift golden SQL churn (results unchanged).
  • The spec delta, design and task list are in openspec/changes/dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/.

Proposal, design, tasks and delta specs: one pyparsing grammar for every Mode-B position, SQL forms, quoted identifiers and SQL string literals, CAST as the database's cast plus portable TRY_CAST, FILTER (WHERE) row semantics, literal-only {var} binding, NULLS FIRST/LAST, stored-text migration, and the importers' legacy parser retired.
New tests (fail until implementation): grammar parse, SQL forms in every
position (SQLite/DuckDB executed, Tier-1 emission), CAST/TRY_CAST incl.
Postgres 15/16/unknown emissions, cast typing, FILTER (WHERE c), variables
as literals, interval/typed literals and clock keywords, NULLS FIRST/LAST,
stored-text migration, importer dependency checks, parser benchmark, and
Postgres / MySQL / SQL Server integration cases.

Retargeted off deleted helpers / flipped to the new string rules:
- test_dev1833_keyword_lexing: _rewrite_sql_like checks -> parse_expr; SQL
  string escapes; "p%" is an identifier; fused-Unicode LIKE operands parse whole
- test_dev1740_case_rewrite: _rewrite_case_when -> parse_expr equivalences
- test_dev1450fix_group2_correctness: double-quoted/backslash literals -> ''
- test_dev1743_validators: stale _preprocess_colons comments trimmed
- test_formula: _rewrite_funcstyle_aggregations / parse_formula -> parse_expr
- test_functional_remedies: remedy asserted through the dbt dependency check
- test_dev1576_heals: colon healing and arity at binding; ndigits rejection
  and function-style alias healing at binding (ruling 2026-10-21)
- test_dev1737_scalar_specs, test_rank_direction: parse_formula -> parse_expr
  / binder
- test_syntax: "hello" is an identifier
- test_variables_planner: SQL quoting of substituted text (ruling 2026-10-21)
- test_mode_a_variable_substitution: escape="python" tests deleted
- parse_filter_expr -> parse_expr in test_translator, test_dev1475,
  test_dev1737_date_functions_parse, test_heal_date_parts,
  test_heal_functional_aggregations, test_mode_b_placeholder_parse,
  test_schema_drift_typed, test_sql_boolean_literal_filters
- test_osi_converter: emitted formula validated by the new grammar
…les to core/enums.py

Deterministic move (dr-refactor) of slayer/engine/syntax.py into core as the
declared child core.syntax; ALL_TRANSFORMS / TIME_TRANSFORMS /
TIMELESS_TRANSFORMS move from core/formula.py to core/enums.py. Approved
harness edits H1-H7: model.c4 child + arrows, legacy baseline 8 -> 7,
system P2 / P10, core and engine arc42 text, regenerated diagrams.
Adds the pyparsing dependency.
… FILTER, quoted identifiers

Replaces the ast.parse pipeline and its text pre-passes with one pyparsing
grammar (parse_filter_expr deleted). Adds the Cast and TemporalLiteral nodes,
CastKey (database cast of the author's type, TRY_CAST lowered per dialect,
Postgres 16+ via the server profile), FILTER (WHERE c) (inputs masked at
binding; star counts and first/last carry the filter on the key), ILIKE,
IS [NOT] DISTINCT FROM, the quoted-identifier hint, the round() ndigits
check, hidden row-level ORDER BY expressions, and canonical names for
unnamed computed dimensions.

Tests respelled for the SQL string rule (backslash escapes and double-quoted
strings no longer literals): test_dev1901_param_binding, test_dev1934_formula_agg,
test_quoted_aggregation_placeholders. Totality registries extended with
CastKey / ilike: test_dev1747_reroot_visitor, test_dev1842_keys_prepend,
test_dev1825_substitute_keys, test_dev1827_value_key_traversal,
test_dev2013_expression_attribution, test_dev1753_last_four_scalars,
test_dev1744_value_expr.
…rter parser

- OrderItem.nulls feeds OrderEntry.nulls; dialects emit a list of order terms
  (build_order_terms) and T-SQL builds its NULL key over the resolved
  projection expression.
- {var} placeholders bind as literals (bind_variables): strings, bare
  number/boolean slots, whole IN lists; structure-changing values rejected;
  date_range bounds keep their own literal substitution. ComputedDimension
  .substituted removed.
- Stored-only migration SlayerModel 15->16, SlayerQuery 6->7, Memory 4->5
  re-spells Python string literals as SQL literals and | as ||; stored
  queries are migrated before the legacy time-literal repair.
- Importers use parse_expr and one namespace-aware dependency check;
  slayer/core/formula.py (parse_formula, FieldSpec) deleted.
- Postgres TRY_CAST reads the server profile only when a plan casts with it;
  the statement timeout probes the profile only where it depends on it.
- Literal dimensions render without a GROUP BY entry.

Test changes (mechanical): version pins bumped to 16/7/5 in
test_stored_upgrade_rank_orders, test_stored_upgrade_backing_sql,
test_dev1934_save_time_formula, test_model_access_caches,
test_model_access_tags, test_rank_direction_migration, test_memory_string_ids,
test_memories_storage, test_sqlite_memories_pk_migration; type narrowing in
test_syntax, test_dev1737_scalar_specs, test_dev1838_kernels,
test_dev1576_heals, test_rank_direction and the dev2101 suites; composite
asserts split and pytest.raises blocks reduced to the call under test in the
dev2101 suites, test_dev1576_heals, test_dev1737_scalar_specs,
test_osi_converter and test_quoted_aggregation_placeholders.
Changed tests: test_syntax::test_scalar_function_with_kwarg_rejected -> test_equals_inside_scalar_call_is_comparison;
test_dev1737_date_functions_parse::TestKeywordArgsRejected -> TestEqualsInDateCallsIsComparison (asserts the error each spelling now raises).
Keyword-slot rejections suggest '==' or parentheses; scalar-call failures over a 'name = value' argument say scalar
functions take positional arguments. Cmp records a single '=' spelling outside its identity. One help sentence in
help.aggregations.
…MIN/MAX

Extends the existing column wrap to aggregate-free row expressions whose row refs are not grouping values (it
crashed with MaterialisationStageError). Docs: order-target table row and explicit nulls placement.
Changed tests: test_dev1733::test_composite_over_declared_aliases_still_rejected -> ..._is_an_expression (+ a sort test);
test_dev1712::test_composite_order_string_now_accepted_at_construction and
test_sql_generator::test_hidden_composite_order_accepted_at_input_validation assert alias / row composites are expressions.
Changed tests: test_cube_converter::test_calculated_measure_with_case_when_is_reported_not_emitted -> ..._is_emitted;
test_distinct_dimension_values::test_filter_post_variable_substitution asserts the literal-values error;
test_dev2101_agg_filter::_filtered_equals_restricted drops the row-count assertion (FILTER keeps empty buckets);
test_dev2101_sql_forms::test_substring_and_position_equal_their_calls orders by id;
test_dev2101_null_ordering::test_no_policy_emits_no_modifier -> test_no_policy_keeps_nulls_last;
test_dev2101_null_ordering::test_tsql_orders_over_the_resolved_expression asserts the subquery column / inlined expression.
Two infix_notation tiers (arithmetic / concat, then predicates) replace the hand-built precedence ladder, and a
keyword lookahead guards the keyword-led atoms; packrat was measured slower. Cold parses ~2.6x faster than the
packrat ladder. Design D2 updated accordingly; basedpyright baseline shrinks.
…teger column

Changed tests: _dev2101_fixtures % predicate/value use quantity (float % deferred to DEV-2120);
test_parameterised_cast_is_postgres_numeric asserts the DECIMAL(10, 2) cast and value;
test_cast_to_json_executes runs raw rows. Example models re-saved at SlayerModel version 16.
@linear

linear Bot commented Oct 22, 2026

Copy link
Copy Markdown

DEV-2101

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 219 files, which is 69 over the limit of 150.

To get a review, reduce the PR to 150 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to Team to raise the limit.

This review couldn't start because sufficient usage credits or metered capacity aren't available. Add credits or update usage-based reviews in the billing tab, then retry.

⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between 56006b6 and 322a892.

⛔ Files ignored due to path filters: 1
  • poetry.lock is excluded by !**/*.lock
📒 Files selected for processing: 219
  • .basedpyright/baseline.json
  • architecture/core.arc42.md
  • architecture/engine.arc42.md
  • architecture/index.yaml
  • architecture/model.c4
  • architecture/system.arc42.md
  • docs/concepts/formulas.md
  • docs/concepts/queries.md
  • docs/concepts/references.md
  • docs/examples/09_lightning_talk/slayer_models/models/jaffle_shop/customers.yaml
  • docs/examples/09_lightning_talk/slayer_models/models/jaffle_shop/items.yaml
  • docs/examples/09_lightning_talk/slayer_models/models/jaffle_shop/orders.yaml
  • docs/examples/09_lightning_talk/slayer_models/models/jaffle_shop/products.yaml
  • docs/examples/09_lightning_talk/slayer_models/models/jaffle_shop/stores.yaml
  • docs/examples/09_lightning_talk/slayer_models/models/jaffle_shop/supplies.yaml
  • docs/examples/09_lightning_talk/slayer_models/models/jaffle_shop/tweets.yaml
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/.openspec.yaml
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/design.md
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/proposal.md
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/specs/aggregations/functional-form/spec.md
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/specs/models/stored-upgrade/spec.md
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/specs/queries/casts/spec.md
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/specs/queries/date-functions/spec.md
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/specs/queries/expression-grammar/spec.md
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/specs/queries/expression-keywords/spec.md
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/specs/queries/positions/spec.md
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/specs/queries/variables/spec.md
  • openspec/changes/archive/2026-10-22-dev-2101-mode-b-as-a-sql-compatible-grammar-custom-parser-sql-forms/tasks.md
  • openspec/specs/aggregations/functional-form/spec.md
  • openspec/specs/models/stored-upgrade/spec.md
  • openspec/specs/queries/casts/spec.md
  • openspec/specs/queries/date-functions/spec.md
  • openspec/specs/queries/expression-grammar/spec.md
  • openspec/specs/queries/expression-keywords/spec.md
  • openspec/specs/queries/positions/spec.md
  • openspec/specs/queries/variables/spec.md
  • pyproject.toml
  • slayer/core/enums.py
  • slayer/core/errors.py
  • slayer/core/formula.py
  • slayer/core/keys.py
  • slayer/core/models.py
  • slayer/core/query.py
  • slayer/core/refs.py
  • slayer/core/syntax.py
  • slayer/cube/converter.py
  • slayer/dbt/converter.py
  • slayer/engine/bind_inputs.py
  • slayer/engine/binding.py
  • slayer/engine/compile/projection.py
  • slayer/engine/compile/shift.py
  • slayer/engine/compile/stages.py
  • slayer/engine/elaborate_env.py
  • slayer/engine/key_metadata.py
  • slayer/engine/model_reads.py
  • slayer/engine/population.py
  • slayer/engine/query_engine.py
  • slayer/engine/reference_closure.py
  • slayer/engine/schema_drift.py
  • slayer/engine/syntax.py
  • slayer/engine/unrelated.py
  • slayer/ir/bound.py
  • slayer/ir/planned.py
  • slayer/ir/terms.py
  • slayer/ir/variables.py
  • slayer/memories/help_content/02_workflow.md
  • slayer/memories/help_content/03_aggregations.md
  • slayer/memories/resolver.py
  • slayer/osi/converter.py
  • slayer/sql/client.py
  • slayer/sql/dialects/_tier2.py
  • slayer/sql/dialects/base.py
  • slayer/sql/dialects/clickhouse.py
  • slayer/sql/dialects/duckdb.py
  • slayer/sql/dialects/mysql.py
  • slayer/sql/dialects/postgres.py
  • slayer/sql/dialects/snowflake.py
  • slayer/sql/dialects/sqlite.py
  • slayer/sql/dialects/tsql.py
  • slayer/sql/generator.py
  • slayer/sql/render/joins.py
  • slayer/sql/render/order_terms.py
  • slayer/sql/render/ranked.py
  • slayer/sql/render/row_expr.py
  • slayer/sql/render/value_expr.py
  • slayer/sql/scope.py
  • slayer/sql/sql_expr.py
  • slayer/sql/sql_predicate.py
  • slayer/storage/base.py
  • slayer/storage/migrations.py
  • slayer/storage/rank_direction_migration.py
  • slayer/storage/sql_string_migration.py
  • slayer/usage_reporting/features/__init__.py
  • tests/_dev1747_fixtures.py
  • tests/_dev2101_fixtures.py
  • tests/_usage_reporting_capture.py
  • tests/facade/test_translator.py
  • tests/golden/consecutive_periods_calendar_sql_baseline.json
  • tests/golden/dev1737_date_add_parity.json
  • tests/golden/dev1739_sql_baseline.json
  • tests/golden/dev1740_regroup_baseline.json
  • tests/golden/dev1745_sql_baseline.json
  • tests/golden/dev1747_sql_baseline.json
  • tests/golden/dev1748_first_last_baseline.json
  • tests/golden/dev1750_sql_baseline.json
  • tests/golden/dev1800_sql_baseline.json
  • tests/golden/dev1824_sql_baseline.json
  • tests/golden/dev1832_sql_baseline.json
  • tests/golden/dev1835_sql_baseline.json
  • tests/golden/dev1837_sql_baseline.json
  • tests/golden/dev1839_sql_baseline.json
  • tests/golden/dev1840_sql_baseline.json
  • tests/golden/dev1841_sql_baseline.json
  • tests/golden/dev1846_sql_baseline.json
  • tests/golden/dev1847_sql_baseline.json
  • tests/golden/dev1859_sql_baseline.json
  • tests/golden/dev1865_sql_baseline.json
  • tests/golden/dev1868_sql_baseline.json
  • tests/golden/dev1892_sql_baseline.json
  • tests/golden/dev1900_sql_baseline.json
  • tests/golden/dev1908_sql_baseline.json
  • tests/golden/dev1909_sql_baseline.json
  • tests/golden/dev1915_sql_baseline.json
  • tests/golden/dev1935_sql_baseline.json
  • tests/golden/dev1942_sql_baseline.json
  • tests/golden/dev1958_sql_baseline.json
  • tests/golden/dev2015_sql_baseline.json
  • tests/integration/test_dev2101_postgres.py
  • tests/integration/test_integration_mysql.py
  • tests/integration/test_integration_sqlserver.py
  • tests/perf/dev2101_old_parser_baseline.json
  • tests/perf/test_dev2101_parser_bench.py
  • tests/test_agg_render_spec.py
  • tests/test_binding.py
  • tests/test_cube_converter.py
  • tests/test_cube_views.py
  • tests/test_dev1450fix_group2_correctness.py
  • tests/test_dev1475_in_tuple_filters.py
  • tests/test_dev1576_heals.py
  • tests/test_dev1708_stage4_cte_scope.py
  • tests/test_dev1712_order_only_hidden_slots.py
  • tests/test_dev1733_order_only_transform_composite.py
  • tests/test_dev1737_date_functions_parse.py
  • tests/test_dev1737_date_functions_typing.py
  • tests/test_dev1737_scalar_specs.py
  • tests/test_dev1740_case_rewrite.py
  • tests/test_dev1743_validators.py
  • tests/test_dev1744_value_expr.py
  • tests/test_dev1745_fragment_joins.py
  • tests/test_dev1746_null_safe_grain.py
  • tests/test_dev1747_reroot_visitor.py
  • tests/test_dev1750_shifted_fragment_joins.py
  • tests/test_dev1753_last_four_scalars.py
  • tests/test_dev1825_substitute_keys.py
  • tests/test_dev1827_value_key_traversal.py
  • tests/test_dev1833_keyword_lexing.py
  • tests/test_dev1838_kernels.py
  • tests/test_dev1842_binder_measure_resolution.py
  • tests/test_dev1842_keys_prepend.py
  • tests/test_dev1847_gate.py
  • tests/test_dev1859_plan_structure.py
  • tests/test_dev1859_transform_row_leaf.py
  • tests/test_dev1901_param_binding.py
  • tests/test_dev1903_first_last_dispatch.py
  • tests/test_dev1903_transform_inputs.py
  • tests/test_dev1934_formula_agg.py
  • tests/test_dev1934_save_time_formula.py
  • tests/test_dev1946_transform_parameter.py
  • tests/test_dev1952_derived_revisit.py
  • tests/test_dev1953_partition_alias.py
  • tests/test_dev1953_partition_membership.py
  • tests/test_dev1954_canonical_paths.py
  • tests/test_dev1958_row_leaf_ban.py
  • tests/test_dev2013_expression_attribution.py
  • tests/test_dev2046_boolean_valued.py
  • tests/test_dev2046_typing.py
  • tests/test_dev2101_agg_filter.py
  • tests/test_dev2101_cast_typing.py
  • tests/test_dev2101_casts.py
  • tests/test_dev2101_date_literals.py
  • tests/test_dev2101_grammar_parse.py
  • tests/test_dev2101_importer_dependencies.py
  • tests/test_dev2101_null_ordering.py
  • tests/test_dev2101_sql_forms.py
  • tests/test_dev2101_stored_upgrade.py
  • tests/test_dev2101_variables.py
  • tests/test_distinct_dimension_values.py
  • tests/test_expression_aggregations.py
  • tests/test_formula.py
  • tests/test_functional_agg_text.py
  • tests/test_functional_aggregations.py
  • tests/test_functional_emission.py
  • tests/test_functional_remedies.py
  • tests/test_heal_date_parts.py
  • tests/test_heal_functional_aggregations.py
  • tests/test_keyword_spelling_hints.py
  • tests/test_memories_resolver_typed.py
  • tests/test_memories_storage.py
  • tests/test_memory_string_ids.py
  • tests/test_mode_a_variable_substitution.py
  • tests/test_mode_b_placeholder_parse.py
  • tests/test_model_access_caches.py
  • tests/test_model_access_tags.py
  • tests/test_order_row_expression_wrap.py
  • tests/test_osi_converter.py
  • tests/test_quoted_aggregation_placeholders.py
  • tests/test_rank_direction.py
  • tests/test_rank_direction_migration.py
  • tests/test_schema_drift_typed.py
  • tests/test_sql_boolean_literal_filters.py
  • tests/test_sql_generator.py
  • tests/test_sqlite_memories_pk_migration.py
  • tests/test_stored_upgrade_backing_sql.py
  • tests/test_stored_upgrade_rank_orders.py
  • tests/test_syntax.py
  • tests/test_transforms_planner.py
  • tests/test_usage_reporting_delivery.py
  • tests/test_usage_reporting_payload.py
  • tests/test_variables_planner.py

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@ZmeiGorynych

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor
⚠️ Action not completed

Review skipped: 209 files exceed the limit of 150.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant