sqlclean-cli 0.1.0__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/Cargo.lock +2 -2
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/Cargo.toml +1 -1
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/PKG-INFO +1 -1
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/_helpers/collection.rs +28 -11
- sqlclean_cli-0.2.0/crates/sqlclean/src/sql_facts/main/mod.rs +2 -0
- sqlclean_cli-0.2.0/crates/sqlclean/src/sql_facts/main/statement_ends.rs +6 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/tests/test_file_facts.rs +51 -1
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/tests/test_types.rs +6 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/engine.rs +16 -2
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/formatter.rs +4 -4
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/printed_layout.rs +19 -26
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/token_layout.rs +20 -2
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_comment_formatter.rs +6 -0
- sqlclean_cli-0.2.0/crates/sqlclean/src/sql_quality/_helpers/safety.rs +708 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/constants.rs +40 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/main/diagnostics.rs +2 -1
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/mod.rs +2 -0
- sqlclean_cli-0.2.0/crates/sqlclean/src/sql_quality/tests/test_safety_rules.rs +193 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/tests/test_types.rs +8 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/tests.rs +2 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/quickstart.md +1 -1
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/rules/overview.md +1 -1
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/rules/reference.md +52 -1
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/formatting/main/format_source.rs +2 -7
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/pyproject.toml +1 -1
- sqlclean_cli-0.1.0/crates/sqlclean/src/sql_facts/main/mod.rs +0 -1
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/README.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/Cargo.toml +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/constants.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/lib.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/_helpers/statements.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/_helpers/tokens.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/main/file_facts.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/tests/helpers.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/tests.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/additional.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/formatter_syntax.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/inline_relations.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/join_predicates.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/parsing.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/terminal_shape.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/constants.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/batch_engine.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/catalogue.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/cross_join_subject.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/default_rules.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/engine.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/fill_finding_path.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/format_requests.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/formatter.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/lint.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/parse_sql.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/main/validate_dialect.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/fixtures/FORMAT_CORPUS_NOTICE.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/fixtures/format_corpus.json +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/helpers.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_authored_tokens.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_batch_lint.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_cross_joins.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_empty_fixture_lint.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_format_corpus.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_function_call_spacing.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_idempotency_reprint.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_layout_rules.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_line_wrap.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_lint_exemptions.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_set_operation_formatter.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_sql_lint.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_types.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_unused_table_alias.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests/test_values_formatter.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/tests.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/_helpers/cte_columns.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/_helpers/declared_keys.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/_helpers/json_parses.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/_helpers/keys.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/_helpers/literals.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/_helpers/ranking.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/_helpers/removal_safety.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/_helpers/setting_help.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/_helpers/syntax.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/main/declared_relation_keys.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/tests/helpers.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/tests/test_json_parses.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/tests/test_quality_rules.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/tests/test_quality_scale.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_quality/types.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/_helpers/builtin_functions.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/_helpers/reserved_keywords.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/_helpers/token_context.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/constants.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/main/builtin_function_names.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/main/canonical_tokens.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/main/case_folding.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/main/is_unquoted_word.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/main/name_positions.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/main/projection_spans.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/main/query_fingerprint.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/main/token_texts.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/reserved_keywords/bigquery.txt +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/reserved_keywords/databricks.txt +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/reserved_keywords/duckdb.txt +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/reserved_keywords/generic.txt +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/reserved_keywords/postgres.txt +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/reserved_keywords/snowflake.txt +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/reserved_keywords/tsql.txt +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/tests/test_canonical_tokens.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/tests/test_types.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_tokens/tests.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/Cargo.toml +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/build.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/SKILL.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/CONTENTS.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/benchmarks.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/cli/check.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/cli/facts.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/cli/fix.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/cli/format.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/cli/rules.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/cli/skills.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/configuration.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/custom-rules/fixes-and-options.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/custom-rules/overview.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/custom-rules/statement-facts.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/custom-rules/testing.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/embedding.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/formatting.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/index.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/skill/references/docs/integrations.md +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/caching/_helpers/entries.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/caching/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/caching/constants.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/caching/main/cache_key.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/caching/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/caching/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/caching/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/caching/tests/test_result_cache.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/caching/tests/test_types.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/caching/tests.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/_helpers/builtin.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/_helpers/catalogue.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/_helpers/custom.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/_helpers/exemptions.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/_helpers/orchestration.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/_helpers/selection.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/constants.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/main/check_sources.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/main/rule_catalogue.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/checking/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/_helpers/check_command.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/_helpers/diffs.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/_helpers/dispatch.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/_helpers/facts_command.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/_helpers/fix_command.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/_helpers/format_command.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/_helpers/rules_command.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/_helpers/skills_command.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/constants.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/main/run.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/command/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/_helpers/file_schema.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/_helpers/loading.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/_helpers/validation.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/constants.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/main/load_config.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/tests/test_load_config.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/tests/test_types.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/config/tests.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/_helpers/matching.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/_helpers/walking.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/main/discover_files.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/main/path_patterns.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/tests/test_discover_files.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/tests/test_types.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/discovery/tests.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/_helpers/edit_selection.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/_helpers/passes.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/constants.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/main/fix_sources.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/tests/helpers.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/tests/test_edit_selection.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/tests/test_types.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/fixing/tests.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/formatting/constants.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/formatting/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/formatting/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/hosting/_helpers/interpreter.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/hosting/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/hosting/_helpers/process.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/hosting/constants.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/hosting/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/hosting/main/run_host.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/hosting/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/hosting/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/lib.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/main.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/positions/main/apply_edits.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/positions/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/positions/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/positions/models.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/positions/tests/test_positions.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/positions/tests/test_types.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/positions/tests.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/reporting/_helpers/location.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/reporting/_helpers/machine.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/reporting/_helpers/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/reporting/_helpers/text.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/reporting/main/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/reporting/main/render_findings.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/reporting/mod.rs +0 -0
- {sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean-cli/src/reporting/models.rs +0 -0
|
@@ -619,7 +619,7 @@ checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
|
|
|
619
619
|
|
|
620
620
|
[[package]]
|
|
621
621
|
name = "sqlclean"
|
|
622
|
-
version = "0.
|
|
622
|
+
version = "0.2.0"
|
|
623
623
|
dependencies = [
|
|
624
624
|
"polyglot-sql",
|
|
625
625
|
"polyglot-sql-function-catalogs",
|
|
@@ -632,7 +632,7 @@ dependencies = [
|
|
|
632
632
|
|
|
633
633
|
[[package]]
|
|
634
634
|
name = "sqlclean-cli"
|
|
635
|
-
version = "0.
|
|
635
|
+
version = "0.2.0"
|
|
636
636
|
dependencies = [
|
|
637
637
|
"clap",
|
|
638
638
|
"globset",
|
{sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/_helpers/collection.rs
RENAMED
|
@@ -15,18 +15,13 @@ use crate::sql_lint::main::parse_sql::parse_sql;
|
|
|
15
15
|
use crate::sql_lint::models::ParsedSql;
|
|
16
16
|
|
|
17
17
|
pub(crate) fn file_facts(sql: &str, dialect: &str) -> Result<FileFacts, String> {
|
|
18
|
-
let
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
let (
|
|
19
|
+
ParsedSql {
|
|
20
|
+
tokens, statements, ..
|
|
21
|
+
},
|
|
22
|
+
ranges,
|
|
23
|
+
) = parsed_statements(sql, dialect)?;
|
|
21
24
|
let characters: Vec<char> = sql.chars().collect();
|
|
22
|
-
let ranges: Vec<StatementTokens> = statement_token_ranges(&tokens);
|
|
23
|
-
if ranges.len() != statements.len() {
|
|
24
|
-
return Err(format!(
|
|
25
|
-
"found {} statements but {} statement ranges",
|
|
26
|
-
statements.len(),
|
|
27
|
-
ranges.len()
|
|
28
|
-
));
|
|
29
|
-
}
|
|
30
25
|
let facts: Vec<StatementFacts> = statements
|
|
31
26
|
.iter()
|
|
32
27
|
.zip(ranges)
|
|
@@ -46,6 +41,28 @@ pub(crate) fn file_facts(sql: &str, dialect: &str) -> Result<FileFacts, String>
|
|
|
46
41
|
Ok(FileFacts { statements: facts })
|
|
47
42
|
}
|
|
48
43
|
|
|
44
|
+
pub(crate) fn statement_ends(sql: &str, dialect: &str) -> Result<Vec<usize>, String> {
|
|
45
|
+
let (_, ranges) = parsed_statements(sql, dialect)?;
|
|
46
|
+
Ok(ranges.iter().map(|range| range.terminated_end).collect())
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/// Parse `sql` and split its tokens into one range per parsed statement.
|
|
50
|
+
fn parsed_statements(
|
|
51
|
+
sql: &str,
|
|
52
|
+
dialect: &str,
|
|
53
|
+
) -> Result<(ParsedSql, Vec<StatementTokens>), String> {
|
|
54
|
+
let parsed: ParsedSql = parse_sql(sql, dialect)?;
|
|
55
|
+
let ranges: Vec<StatementTokens> = statement_token_ranges(&parsed.tokens);
|
|
56
|
+
if ranges.len() != parsed.statements.len() {
|
|
57
|
+
return Err(format!(
|
|
58
|
+
"found {} statements but {} statement ranges",
|
|
59
|
+
parsed.statements.len(),
|
|
60
|
+
ranges.len()
|
|
61
|
+
));
|
|
62
|
+
}
|
|
63
|
+
Ok((parsed, ranges))
|
|
64
|
+
}
|
|
65
|
+
|
|
49
66
|
/// One parsed statement, its tokens and the end offset of its terminator.
|
|
50
67
|
struct StatementSource<'a> {
|
|
51
68
|
index: usize,
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//! Where each statement of one SQL file ends, without collecting its facts.
|
|
2
|
+
|
|
3
|
+
/// Parse `sql` under `dialect` and return the end of each statement, after its terminator.
|
|
4
|
+
pub fn statement_ends(sql: &str, dialect: &str) -> Result<Vec<usize>, String> {
|
|
5
|
+
crate::sql_facts::_helpers::collection::statement_ends(sql, dialect)
|
|
6
|
+
}
|
{sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_facts/tests/test_file_facts.rs
RENAMED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
use crate::sql_facts::main::file_facts::file_facts;
|
|
2
|
+
use crate::sql_facts::main::statement_ends::statement_ends;
|
|
2
3
|
use crate::sql_facts::models::{FileFacts, StatementFacts};
|
|
3
4
|
use crate::sql_facts::tests::helpers::text;
|
|
4
|
-
use crate::sql_facts::tests::test_types::{
|
|
5
|
+
use crate::sql_facts::tests::test_types::{
|
|
6
|
+
ParseOutcomeTestCase, StatementEndsTestCase, StatementFactsTestCase,
|
|
7
|
+
};
|
|
5
8
|
|
|
6
9
|
const TWO_STATEMENTS: &str = "WITH recent AS (SELECT o.order_id, o.* FROM shop.orders AS o WHERE o.total > 10)\n\
|
|
7
10
|
SELECT r.order_id, UPPER(c.name) AS name, 'é' AS mark\n\
|
|
@@ -229,3 +232,50 @@ fn given_sql_text_when_collecting_facts_then_only_unparseable_sql_is_an_error()
|
|
|
229
232
|
);
|
|
230
233
|
}
|
|
231
234
|
}
|
|
235
|
+
|
|
236
|
+
#[test]
|
|
237
|
+
fn given_sql_text_when_finding_statement_ends_then_each_ends_after_its_terminator() {
|
|
238
|
+
let test_cases = [
|
|
239
|
+
StatementEndsTestCase {
|
|
240
|
+
description: "a comment after a terminator starts the next statement's text",
|
|
241
|
+
sql: "SELECT 'é;' AS a; -- next; note\nSELECT 2 /* end; */",
|
|
242
|
+
expected_statements: Some(&["SELECT 'é;' AS a;", " -- next; note\nSELECT 2"]),
|
|
243
|
+
},
|
|
244
|
+
StatementEndsTestCase {
|
|
245
|
+
description: "empty statements between semicolons are skipped",
|
|
246
|
+
sql: ";; SELECT 1;;SELECT 2;",
|
|
247
|
+
expected_statements: Some(&[";; SELECT 1;", ";SELECT 2;"]),
|
|
248
|
+
},
|
|
249
|
+
StatementEndsTestCase {
|
|
250
|
+
description: "a file of only comments has no statements",
|
|
251
|
+
sql: "-- only a note; nothing else\n/* still; nothing */\n",
|
|
252
|
+
expected_statements: Some(&[]),
|
|
253
|
+
},
|
|
254
|
+
StatementEndsTestCase {
|
|
255
|
+
description: "an unparseable statement is an error, not a split",
|
|
256
|
+
sql: "SELECT 1; SELECT FROM WHERE (",
|
|
257
|
+
expected_statements: None,
|
|
258
|
+
},
|
|
259
|
+
];
|
|
260
|
+
for test_case in &test_cases {
|
|
261
|
+
let characters: Vec<char> = test_case.sql.chars().collect();
|
|
262
|
+
let statements: Option<Vec<String>> = statement_ends(test_case.sql, "duckdb")
|
|
263
|
+
.map(|ends| {
|
|
264
|
+
let starts = std::iter::once(0).chain(ends.iter().copied());
|
|
265
|
+
starts
|
|
266
|
+
.zip(ends.iter().copied())
|
|
267
|
+
.map(|(start, end)| characters[start..end].iter().collect())
|
|
268
|
+
.collect()
|
|
269
|
+
})
|
|
270
|
+
.ok();
|
|
271
|
+
let texts: Option<Vec<&str>> = statements
|
|
272
|
+
.as_ref()
|
|
273
|
+
.map(|statements| statements.iter().map(String::as_str).collect());
|
|
274
|
+
assert_eq!(
|
|
275
|
+
texts.as_deref(),
|
|
276
|
+
test_case.expected_statements,
|
|
277
|
+
"{}",
|
|
278
|
+
test_case.description
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
@@ -19,3 +19,9 @@ pub(crate) struct ParseOutcomeTestCase {
|
|
|
19
19
|
pub(crate) sql: &'static str,
|
|
20
20
|
pub(crate) expected_statements: Option<usize>,
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
pub(crate) struct StatementEndsTestCase {
|
|
24
|
+
pub(crate) description: &'static str,
|
|
25
|
+
pub(crate) sql: &'static str,
|
|
26
|
+
pub(crate) expected_statements: Option<&'static [&'static str]>,
|
|
27
|
+
}
|
|
@@ -238,7 +238,7 @@ const FINAL_CTE_NAME: LintRuleMetadata = LintRuleMetadata {
|
|
|
238
238
|
remediation: "Name the last top-level CTE final and rename any other final CTE; SQC035 checks the terminal SELECT.",
|
|
239
239
|
};
|
|
240
240
|
|
|
241
|
-
pub(crate) const DEFAULT_RULES: [&str;
|
|
241
|
+
pub(crate) const DEFAULT_RULES: [&str; 19] = [
|
|
242
242
|
NULL_COMPARISON.code,
|
|
243
243
|
IMPLICIT_CARTESIAN_JOIN.code,
|
|
244
244
|
JOIN_WITHOUT_CONDITION.code,
|
|
@@ -252,9 +252,15 @@ pub(crate) const DEFAULT_RULES: [&str; 13] = [
|
|
|
252
252
|
NULL_NOT_IN.code,
|
|
253
253
|
SET_ARITY_MISMATCH.code,
|
|
254
254
|
INLINE_QUERY_RELATION.code,
|
|
255
|
+
crate::sql_quality::constants::DUPLICATE_CTE_NAME.code,
|
|
256
|
+
crate::sql_quality::constants::NULL_MATCH.code,
|
|
257
|
+
crate::sql_quality::constants::LITERAL_ZERO_DIVISION.code,
|
|
258
|
+
crate::sql_quality::constants::NATURAL_JOIN.code,
|
|
259
|
+
crate::sql_quality::constants::REVERSED_BETWEEN.code,
|
|
260
|
+
crate::sql_quality::constants::MISPLACED_AGGREGATE.code,
|
|
255
261
|
];
|
|
256
262
|
|
|
257
|
-
const ALL_RULE_METADATA: [&LintRuleMetadata;
|
|
263
|
+
const ALL_RULE_METADATA: [&LintRuleMetadata; 53] = [
|
|
258
264
|
&NULL_COMPARISON,
|
|
259
265
|
&IMPLICIT_CARTESIAN_JOIN,
|
|
260
266
|
&JOIN_WITHOUT_CONDITION,
|
|
@@ -300,6 +306,14 @@ const ALL_RULE_METADATA: [&LintRuleMetadata; 45] = [
|
|
|
300
306
|
&crate::sql_quality::constants::RANKING_SORT_CAP,
|
|
301
307
|
&crate::sql_quality::constants::LONG_LITERAL,
|
|
302
308
|
&crate::sql_quality::constants::REPEATED_JSON_PARSE,
|
|
309
|
+
&crate::sql_quality::constants::DUPLICATE_CTE_NAME,
|
|
310
|
+
&crate::sql_quality::constants::NULL_MATCH,
|
|
311
|
+
&crate::sql_quality::constants::LITERAL_ZERO_DIVISION,
|
|
312
|
+
&crate::sql_quality::constants::UNFILTERED_WRITE,
|
|
313
|
+
&crate::sql_quality::constants::INSERT_WITHOUT_COLUMNS,
|
|
314
|
+
&crate::sql_quality::constants::NATURAL_JOIN,
|
|
315
|
+
&crate::sql_quality::constants::REVERSED_BETWEEN,
|
|
316
|
+
&crate::sql_quality::constants::MISPLACED_AGGREGATE,
|
|
303
317
|
];
|
|
304
318
|
|
|
305
319
|
fn is_ceremonial_cte_name(name: &str) -> bool {
|
{sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/formatter.rs
RENAMED
|
@@ -187,11 +187,11 @@ impl Layout<'_> {
|
|
|
187
187
|
authored: &AuthoredSql<'_>,
|
|
188
188
|
oracle: &OracleLayout,
|
|
189
189
|
) -> Result<(String, BTreeMap<usize, KeywordRecase>, TokenTexts), String> {
|
|
190
|
-
let
|
|
190
|
+
let print = print_authored_tokens(authored, oracle, self.dialect)?;
|
|
191
191
|
let no_widths: HashMap<String, usize> = HashMap::new();
|
|
192
192
|
let token_widths = self.wrap.map_or(&no_widths, |wrap| wrap.token_widths);
|
|
193
|
-
let Some(mut sql) = PrintedSql::
|
|
194
|
-
return Ok((
|
|
193
|
+
let Some(mut sql) = PrintedSql::new(&print.sql, &print.tokens, token_widths) else {
|
|
194
|
+
return Ok((print.sql, print.recases, print.texts));
|
|
195
195
|
};
|
|
196
196
|
sql.set_indent(self.indent);
|
|
197
197
|
sql.attach_commas_before_comments();
|
|
@@ -203,7 +203,7 @@ impl Layout<'_> {
|
|
|
203
203
|
wrap_lines(&mut sql, wrap.line_width);
|
|
204
204
|
}
|
|
205
205
|
sql.lead_operators_of_multiline_operands();
|
|
206
|
-
Ok((sql.render(), recases, texts))
|
|
206
|
+
Ok((sql.render(), print.recases, print.texts))
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
|
{sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/printed_layout.rs
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
//! Printed SQL as tokens and gaps, with clause layout rules and line-width wrapping.
|
|
2
2
|
|
|
3
3
|
use std::collections::HashMap;
|
|
4
|
+
use std::ops::Range;
|
|
4
5
|
|
|
5
|
-
use polyglot_sql::Dialect;
|
|
6
6
|
use polyglot_sql::tokens::TokenType;
|
|
7
7
|
|
|
8
8
|
use crate::sql_lint::constants::OPEN_PARENTHESIS;
|
|
@@ -87,35 +87,28 @@ struct Line {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
impl<'a> PrintedSql<'a> {
|
|
90
|
-
|
|
90
|
+
/// Split printed `sql` at its token byte ranges; `None` when it has no tokens.
|
|
91
|
+
pub(crate) fn new(
|
|
91
92
|
sql: &str,
|
|
92
|
-
|
|
93
|
+
printed_tokens: &[(Range<usize>, TokenType)],
|
|
93
94
|
token_widths: &'a HashMap<String, usize>,
|
|
94
|
-
) ->
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
let characters: Vec<char> = sql.chars().collect();
|
|
102
|
-
let mut texts: Vec<String> = Vec::with_capacity(tokens.len());
|
|
103
|
-
let mut gaps: Vec<String> = Vec::with_capacity(tokens.len() + 1);
|
|
95
|
+
) -> Option<Self> {
|
|
96
|
+
if printed_tokens.is_empty() {
|
|
97
|
+
return None;
|
|
98
|
+
}
|
|
99
|
+
let mut texts: Vec<String> = Vec::with_capacity(printed_tokens.len());
|
|
100
|
+
let mut gaps: Vec<String> = Vec::with_capacity(printed_tokens.len() + 1);
|
|
104
101
|
let mut previous_end = 0_usize;
|
|
105
|
-
for
|
|
106
|
-
gaps.push(
|
|
107
|
-
texts.push(
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
);
|
|
112
|
-
previous_end = token.span.end;
|
|
113
|
-
}
|
|
114
|
-
gaps.push(characters[previous_end..].iter().collect());
|
|
102
|
+
for (range, _) in printed_tokens {
|
|
103
|
+
gaps.push(sql[previous_end..range.start].to_owned());
|
|
104
|
+
texts.push(sql[range.clone()].to_owned());
|
|
105
|
+
previous_end = range.end;
|
|
106
|
+
}
|
|
107
|
+
gaps.push(sql[previous_end..].to_owned());
|
|
115
108
|
let (depths, partners) = bracket_structure(&texts);
|
|
116
109
|
let locked = vec![false; texts.len() + 1];
|
|
117
|
-
|
|
118
|
-
kinds:
|
|
110
|
+
Some(Self {
|
|
111
|
+
kinds: printed_tokens.iter().map(|(_, kind)| *kind).collect(),
|
|
119
112
|
tokens: texts,
|
|
120
113
|
gaps,
|
|
121
114
|
depths,
|
|
@@ -123,7 +116,7 @@ impl<'a> PrintedSql<'a> {
|
|
|
123
116
|
locked,
|
|
124
117
|
token_widths,
|
|
125
118
|
indent: PARSED_INDENT,
|
|
126
|
-
})
|
|
119
|
+
})
|
|
127
120
|
}
|
|
128
121
|
|
|
129
122
|
fn len(&self) -> usize {
|
{sqlclean_cli-0.1.0 → sqlclean_cli-0.2.0}/crates/sqlclean/src/sql_lint/_helpers/token_layout.rs
RENAMED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
//! Print authored SQL tokens with whitespace taken from a parse-tree layout oracle.
|
|
2
2
|
|
|
3
3
|
use std::collections::{BTreeMap, BTreeSet};
|
|
4
|
+
use std::ops::Range;
|
|
4
5
|
|
|
5
6
|
use polyglot_sql::Dialect;
|
|
6
7
|
use polyglot_sql::tokens::{Token, TokenType};
|
|
@@ -67,6 +68,15 @@ impl Lexeme {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
71
|
+
/// Authored tokens printed against an oracle, with what the token check needs about them.
|
|
72
|
+
pub(crate) struct AuthoredPrint {
|
|
73
|
+
pub(crate) sql: String,
|
|
74
|
+
/// The byte range and type of each printed token; comments and whitespace lie between them.
|
|
75
|
+
pub(crate) tokens: Vec<(Range<usize>, TokenType)>,
|
|
76
|
+
pub(crate) recases: BTreeMap<usize, KeywordRecase>,
|
|
77
|
+
pub(crate) texts: TokenTexts,
|
|
78
|
+
}
|
|
79
|
+
|
|
70
80
|
/// The source text and case-fold flag of every token, read once for the token check.
|
|
71
81
|
pub(crate) struct TokenTexts {
|
|
72
82
|
texts: Vec<String>,
|
|
@@ -227,7 +237,7 @@ pub(crate) fn print_authored_tokens(
|
|
|
227
237
|
source: &AuthoredSql<'_>,
|
|
228
238
|
oracle: &OracleLayout,
|
|
229
239
|
dialect: &Dialect,
|
|
230
|
-
) -> Result<
|
|
240
|
+
) -> Result<AuthoredPrint, String> {
|
|
231
241
|
let AuthoredSql {
|
|
232
242
|
sql,
|
|
233
243
|
tokens,
|
|
@@ -241,6 +251,7 @@ pub(crate) fn print_authored_tokens(
|
|
|
241
251
|
let mut output = String::with_capacity(sql.len() + sql.len() / 4);
|
|
242
252
|
let string_breaks = string_breaks(sql, tokens);
|
|
243
253
|
let mut recases: BTreeMap<usize, KeywordRecase> = BTreeMap::new();
|
|
254
|
+
let mut printed_tokens: Vec<(Range<usize>, TokenType)> = Vec::with_capacity(tokens.len());
|
|
244
255
|
for (index, lexeme) in authored.iter().enumerate() {
|
|
245
256
|
let forced_break = string_breaks.contains(&index) && !separators[index].contains('\n');
|
|
246
257
|
let forced: String;
|
|
@@ -281,7 +292,9 @@ pub(crate) fn print_authored_tokens(
|
|
|
281
292
|
},
|
|
282
293
|
);
|
|
283
294
|
}
|
|
295
|
+
let start = output.len();
|
|
284
296
|
output.push_str(&printed_text(lexeme, guide));
|
|
297
|
+
printed_tokens.push((start..output.len(), tokens[index].token_type));
|
|
285
298
|
let trailing = &attached[index].trailing;
|
|
286
299
|
for (position, comment) in trailing.iter().enumerate() {
|
|
287
300
|
output.push(' ');
|
|
@@ -312,7 +325,12 @@ pub(crate) fn print_authored_tokens(
|
|
|
312
325
|
texts.texts.push(lexeme.raw);
|
|
313
326
|
texts.foldable.push(lexeme.foldable);
|
|
314
327
|
}
|
|
315
|
-
Ok(
|
|
328
|
+
Ok(AuthoredPrint {
|
|
329
|
+
sql: output,
|
|
330
|
+
tokens: printed_tokens,
|
|
331
|
+
recases,
|
|
332
|
+
texts,
|
|
333
|
+
})
|
|
316
334
|
}
|
|
317
335
|
|
|
318
336
|
/// Refuse output that changes anything but layout, fold-set case, and recorded keyword recases.
|
|
@@ -74,6 +74,12 @@ fn given_trailing_comments_after_the_last_token_when_formatting_then_no_newline_
|
|
|
74
74
|
expected_sql: "SELECT 1 AS order_id\nFROM orders /* latest orders */",
|
|
75
75
|
expected_changed: false,
|
|
76
76
|
},
|
|
77
|
+
test_types::FormatTestCase {
|
|
78
|
+
description: "multibyte comments and literals keep every later token in place",
|
|
79
|
+
sql: "select 'café' as naïve, -- prix en €\n ü.x from t as ü /* 日本 */ where ü.y = 'ß'",
|
|
80
|
+
expected_sql: "SELECT\n 'café' AS naïve, -- prix en €\n ü.x\nFROM t AS ü /* 日本 */\nWHERE ü.y = 'ß'",
|
|
81
|
+
expected_changed: true,
|
|
82
|
+
},
|
|
77
83
|
];
|
|
78
84
|
for test_case in &test_cases {
|
|
79
85
|
let response = format_json(
|