sqlty 0.4.0__tar.gz → 0.5.1__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.
- {sqlty-0.4.0 → sqlty-0.5.1}/PKG-INFO +19 -18
- {sqlty-0.4.0 → sqlty-0.5.1}/README.md +13 -13
- {sqlty-0.4.0 → sqlty-0.5.1}/pyproject.toml +23 -5
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/Cargo.lock +7 -7
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/Cargo.toml +2 -2
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-ext/src/lib.rs +46 -1
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-format/Cargo.toml +2 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-format/src/lib.rs +3 -3
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-lsp/src/actions.rs +1 -1
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-lsp/src/tests.rs +1 -1
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/checker.rs +25 -16
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/config.rs +99 -1
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/queries.rs +19 -4
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/rewriter.rs +18 -7
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/rules.rs +6 -1
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/api.rs +1 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/complete.rs +41 -8
- sqlty-0.5.1/rust/crates/sqlty-sql/src/analyzer/databases.rs +195 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/explain.rs +1 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/hover.rs +1 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/mod.rs +4 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/params.rs +1 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/star_expand.rs +1 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/mod.rs +2 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/resolve.rs +1 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/skills/sqlty/SKILL.md +8 -8
- {sqlty-0.4.0 → sqlty-0.5.1}/skills/sqlty-adopt/SKILL.md +12 -7
- {sqlty-0.4.0 → sqlty-0.5.1}/skills/sqlty-breaking/SKILL.md +2 -2
- {sqlty-0.4.0 → sqlty-0.5.1}/skills/sqlty-check/SKILL.md +52 -9
- {sqlty-0.4.0 → sqlty-0.5.1}/skills/sqlty-ci/SKILL.md +4 -4
- {sqlty-0.4.0 → sqlty-0.5.1}/skills/sqlty-rewrite/SKILL.md +4 -4
- {sqlty-0.4.0 → sqlty-0.5.1}/skills/sqlty-server/SKILL.md +4 -4
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_check.py +13 -5
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_cli.py +115 -29
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_config.py +41 -9
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_core.pyi +9 -1
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_drivers.py +147 -44
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_helpers.py +36 -11
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_lint.py +9 -2
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_source.py +5 -3
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/core.py +24 -4
- sqlty-0.5.1/src/sqlty/lexer.py +74 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/param-count-mismatch.md +7 -4
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/param-type-mismatch.md +9 -6
- sqlty-0.5.1/src/sqlty/rules/unknown-database.md +30 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/LICENSE +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-ext/Cargo.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-ext/build.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-ext/src/config.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-ext/src/server.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-lsp/Cargo.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-lsp/src/completion.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-lsp/src/highlight.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-lsp/src/hover.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-lsp/src/lib.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-lsp/src/text.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-lsp/src/uri.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-lsp/src/worker.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/Cargo.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/clippy.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/edit.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/fixer.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/lib.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/locate.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/options.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/params.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/scan.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/template.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-python/src/tokens.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/Cargo.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/build.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/clippy.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/README.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/common/aggregates.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/common/arithmetic.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/common/comparison.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/common/concat.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/common/conditional.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/common/datetime.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/common/json.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/common/math.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/common/strings.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/common/window.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/compile.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/dialects.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/aggregates.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/arithmetic.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/bits.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/comparison.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/concat.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/conditional.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/datetime.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/encryption.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/json.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/math.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/misc.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/spatial.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/strings.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/mysql/system.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/admin.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/aggregates.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/arithmetic.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/arrays.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/binary.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/comparison.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/concat.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/conditional.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/datetime.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/enums.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/events.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/extensions.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/formatting.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/geometry.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/json.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/math.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/merge.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/network.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/ranges.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/rows.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/sequences.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/series.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/strings.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/system.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/textsearch.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/uuid.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/postgres/xml.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/sqlite/aggregates.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/sqlite/arithmetic.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/sqlite/bitwise.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/sqlite/datetime.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/sqlite/fts.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/sqlite/json.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/sqlite/math.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/sqlite/scalar.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/rules/sqlite/strings.inference.toml +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/dialect.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/dml.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/entities.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/expr.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/fanout.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/functions.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/grouping.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/hashing.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/inference.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/input.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/json.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/literals.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/memo.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/merged_star.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/names.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/narrowing.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/nullability.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/operators.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/pg_record_functions.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/planner_hints.sql +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/preprocess.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/query.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/references.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/registry.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/resolve.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/respell.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/scope.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__dml__tests__returning_columns_in_queries.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__expr__tests__arrays_and_subscripts.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__expr__tests__case_expressions.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__expr__tests__casts.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__expr__tests__casts_without_a_schema_do_not_complain.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__expr__tests__composite_fields_and_json_access.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__expr__tests__literals_and_unary_operators.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__expr__tests__misc_expressions.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__expr__tests__mysql_and_sqlite_expressions.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__functions__tests__aggregates_in_postgres.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__functions__tests__function_availability_differs_by_dialect.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__functions__tests__return_types_follow_the_argument.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__functions__tests__unknown_functions_are_untyped_and_explained.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__literals__tests__value_sets_flow_through_expressions.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__names__tests__column_names_follow_postgres_figure_colname.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__operators__tests__arithmetic_promotes_numbers_and_types_date_math.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__operators__tests__binary_operators_in_queries.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__operators__tests__common_type_follows_postgres_union_rules.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__operators__tests__division_differs_between_postgres_and_mysql.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__query__tests__column_names_come_from_the_first_branch.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__query__tests__ctes.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__query__tests__dialects_name_and_type_the_same_query_differently.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__query__tests__projection_forms.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__query__tests__recursive_ctes_settle_nullability.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__query__tests__set_operations_combine_nullability.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__query__tests__set_operations_unify_types.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__query__tests__statements_that_are_not_queries_have_no_columns.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__query__tests__unsupported_query_forms_are_explained.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__query__tests__values_lists.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__resolve__tests__ambiguous_names_are_reported_once_per_query.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__resolve__tests__cte_columns_are_resolved_like_tables.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__resolve__tests__names_are_not_judged_without_a_schema.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__resolve__tests__nullability_comes_from_the_declaration.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__resolve__tests__quoted_names_keep_their_case_in_postgres_only.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__resolve__tests__star_over_unreadable_sources_names_the_reason.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__resolve__tests__system_columns_exist_without_being_declared.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__resolve__tests__unknown_names_say_what_is_missing.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__resolve__tests__unqualified_names_resolve_to_the_first_source_that_has_them.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__scope__tests__correlated_subqueries_see_the_outer_scope.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__scope__tests__derived_tables_ctes_and_views.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__scope__tests__nullability_follows_the_join_kind.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__scope__tests__opaque_sources_explain_themselves.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__scope__tests__star_expansion_over_joins.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/snapshots/sqlty_sql__analyzer__scope__tests__table_names_fold_by_dialect.snap +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/sql_type.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/suggest.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/table_functions.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/test_support.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/tests.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/text_names.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/tokens.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/analyzer/typed.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/alter.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/builtin_catalog.sql +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/columns.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/index.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/joins.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/loader.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/names.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/pg_catalog_views.sql +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/catalog/read.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/ddl.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/diagnostics.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/highlight.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/json.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/lib.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/placeholders.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/src/values.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/tests/inference_compiler.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/rust/crates/sqlty-sql/tests/timing.rs +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/__init__.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/__main__.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_breaking.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_decode.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_gitignore.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_json_shape.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_json_types.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_lsp_breaking.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_lsp_bridge.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_params.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_psycopg.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_queries.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_sarif.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_snapshot.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/__init__.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/_stdlib.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/ast_fields.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/compat.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/extract.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/generic.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/info.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/pydantic_types.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/stdlib.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/subtype.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_type_extractor/symbols.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/_variants.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/drivers/psycopg.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/magic.py +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/py.typed +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/ambiguous-column.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/chasm-join.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/column-count-mismatch.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/column-name-mismatch.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/column-type-mismatch.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/dynamic-query.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/entity-mismatch.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/fanout-aggregate.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/fstring-skipped.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/inline-sql-comment.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/insert-missing-column.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/insert-value-count.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/json-shape-mismatch.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/literal-mismatch.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/mysql-sql-marker.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/narrow-type.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/nullable-mismatch.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/params-type-mismatch.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/redundant-literal.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/redundant-optional.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/select-star-no-schema.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/select-star.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/sqruff.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/stale-rewrite.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/stale-type.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/tstring-skipped.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/typeddict-inheritance.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/typeddict-key-mismatch.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/unchecked-query.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/ungrouped-column.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/unknown-column.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/unknown-function.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/unknown-table.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/unknown-type.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/unparsed-query.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/unproven-join.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/unsupported-syntax.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/untyped-query.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty/rules/unused-ignore.md +0 -0
- {sqlty-0.4.0 → sqlty-0.5.1}/src/sqlty_magic.pth +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlty
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.1
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Environment :: Console
|
|
6
6
|
Classifier: Intended Audience :: Developers
|
|
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Rust
|
|
|
12
12
|
Classifier: Programming Language :: SQL
|
|
13
13
|
Classifier: Topic :: Software Development :: Code Generators
|
|
14
14
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
|
15
16
|
Classifier: Topic :: Database
|
|
16
17
|
Classifier: Typing :: Typed
|
|
17
18
|
Requires-Dist: pathspec>=0.12.1
|
|
@@ -19,15 +20,15 @@ Requires-Dist: typing-extensions>=4.15.0 ; python_full_version < '3.15'
|
|
|
19
20
|
Requires-Dist: psycopg>=3.2.12 ; extra == 'psycopg'
|
|
20
21
|
Provides-Extra: psycopg
|
|
21
22
|
License-File: LICENSE
|
|
22
|
-
Summary: Type-safe SQL
|
|
23
|
-
Keywords: sql,type-
|
|
23
|
+
Summary: Type-safe raw SQL for Python: row and parameter types inferred from your SQL and schema, no ORM or database needed
|
|
24
|
+
Keywords: sql,raw-sql,type-safety,type-checking,type-hints,static-analysis,linter,mypy,pyright,ty,postgresql,sqlite,mysql,psycopg,migrations,code-generation,orm-alternative
|
|
24
25
|
Author-email: Jiri Kuncar <jiri.kuncar@gmail.com>
|
|
25
26
|
License-Expression: MIT
|
|
26
27
|
Requires-Python: >=3.14
|
|
27
28
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
28
29
|
Project-URL: Changelog, https://github.com/jirikuncar/sqlty/releases
|
|
29
|
-
Project-URL: Documentation, https://
|
|
30
|
-
Project-URL: Homepage, https://
|
|
30
|
+
Project-URL: Documentation, https://sqlty.kuncar.dev/
|
|
31
|
+
Project-URL: Homepage, https://sqlty.kuncar.dev/
|
|
31
32
|
Project-URL: Issues, https://github.com/jirikuncar/sqlty/issues
|
|
32
33
|
Project-URL: Repository, https://github.com/jirikuncar/sqlty
|
|
33
34
|
|
|
@@ -56,13 +57,13 @@ migration that changes a column is caught in review, not in production.
|
|
|
56
57
|
(<a href="https://github.com/jirikuncar/sqlty/blob/main/docs/assets/demo.tape">view source</a>)
|
|
57
58
|
</p>
|
|
58
59
|
|
|
59
|
-
**Documentation: [
|
|
60
|
+
**Documentation: [sqlty.kuncar.dev](https://sqlty.kuncar.dev/)**
|
|
60
61
|
|
|
61
62
|
**Fits if** you write SQL as string literals on Python 3.14+, against
|
|
62
63
|
PostgreSQL, SQLite or MySQL, with a schema dump or SQL migrations in the
|
|
63
64
|
repository. Rows are typed end to end with psycopg 3; with other drivers sqlty
|
|
64
65
|
checks the query and its parameters, and you annotate what the cursor returns
|
|
65
|
-
([Drivers](https://
|
|
66
|
+
([Drivers](https://sqlty.kuncar.dev/guide/drivers-and-orms/)).
|
|
66
67
|
|
|
67
68
|
> **Beta.** APIs and configuration may change before 1.0. Feedback welcome in
|
|
68
69
|
> [GitHub Issues](https://github.com/jirikuncar/sqlty/issues).
|
|
@@ -124,10 +125,10 @@ query = SQL[tuple[int, str]]("--sql\nSELECT id, email FROM users")
|
|
|
124
125
|
caller that now needs a `None` check. `narrow-type` is an error, so CI fails on
|
|
125
126
|
it; an annotation that is only wider than the rows, such as `str | None` for a
|
|
126
127
|
column made `NOT NULL`, is a `stale-type` warning
|
|
127
|
-
([CI](https://
|
|
128
|
+
([CI](https://sqlty.kuncar.dev/recipes/ci/)). For rolling deploys,
|
|
128
129
|
`sqlty breaking --against origin/main` exits 1 when old code breaks on the new
|
|
129
130
|
schema or new code on the old one
|
|
130
|
-
([Breaking schema changes](https://
|
|
131
|
+
([Breaking schema changes](https://sqlty.kuncar.dev/guide/breaking-changes/)).
|
|
131
132
|
|
|
132
133
|
### A row type that doesn't match its query
|
|
133
134
|
|
|
@@ -144,7 +145,7 @@ query = SQL[User]("--sql\nSELECT id::INTEGER, name::TEXT FROM users")
|
|
|
144
145
|
```
|
|
145
146
|
|
|
146
147
|
`TypedDict`, `NamedTuple`, dataclasses and Pydantic models are all checked
|
|
147
|
-
([Row types](https://
|
|
148
|
+
([Row types](https://sqlty.kuncar.dev/guide/row-types/)).
|
|
148
149
|
|
|
149
150
|
### Wrong parameters, misspelled columns
|
|
150
151
|
|
|
@@ -176,11 +177,11 @@ conn.execute(SQL[tuple[str | None]]("--sql\nSELECT email FROM users WHERE id = ?
|
|
|
176
177
|
conn.execute("--sql\nSELECT emial FROM users")
|
|
177
178
|
```
|
|
178
179
|
|
|
179
|
-
`?`, `$1`, `%s` and `:name` placeholders are checked on sqlite3,
|
|
180
|
-
asyncpg calls ([Parameters](https://
|
|
180
|
+
`?`, `$1`, `%s` and `:name` placeholders are checked on sqlite3, aiosqlite,
|
|
181
|
+
psycopg and asyncpg calls ([Parameters](https://sqlty.kuncar.dev/guide/parameters/)).
|
|
181
182
|
These are the mistakes coding agents make: every problem is one
|
|
182
183
|
`file:line: [rule] message` line and a non-zero exit code they can act on, and
|
|
183
|
-
the [sqlty skills](https://
|
|
184
|
+
the [sqlty skills](https://sqlty.kuncar.dev/recipes/agents/) teach
|
|
184
185
|
them the conventions. In Claude Code, `/plugin install sqlty --marketplace jirikuncar/sqlty`
|
|
185
186
|
installs them.
|
|
186
187
|
|
|
@@ -196,13 +197,13 @@ sqlty strip . # undo: back to plain strings
|
|
|
196
197
|
|
|
197
198
|
`rewrite` and `strip` only touch the wrapper, never the SQL, so you can adopt
|
|
198
199
|
sqlty one module at a time and back out. New project:
|
|
199
|
-
[Quickstart](https://
|
|
200
|
-
[Migration](https://
|
|
200
|
+
[Quickstart](https://sqlty.kuncar.dev/quickstart/). Existing codebase:
|
|
201
|
+
[Migration](https://sqlty.kuncar.dev/recipes/migration/), starting
|
|
201
202
|
with `pg_dump --schema-only app > schema.sql`. In the editor:
|
|
202
|
-
[VS Code](https://
|
|
203
|
+
[VS Code](https://sqlty.kuncar.dev/recipes/vscode/).
|
|
203
204
|
|
|
204
205
|
Not a fit for ORMs, SQL built at runtime, or runtime validation;
|
|
205
|
-
[Why SQLTy?](https://
|
|
206
|
+
[Why SQLTy?](https://sqlty.kuncar.dev/motivation/) compares it with
|
|
206
207
|
sqlc, sqlx, PgTyped and others.
|
|
207
208
|
|
|
208
209
|
## About
|
|
@@ -213,6 +214,6 @@ developed with AI coding agents, mainly Claude Code; every change is reviewed by
|
|
|
213
214
|
a maintainer (see the
|
|
214
215
|
[AI-assisted contributions](https://github.com/jirikuncar/sqlty/blob/main/CONTRIBUTING.md#ai-assisted-contributions)
|
|
215
216
|
policy). [Contributing](https://github.com/jirikuncar/sqlty/blob/main/CONTRIBUTING.md) ·
|
|
216
|
-
[Credits](https://
|
|
217
|
+
[Credits](https://sqlty.kuncar.dev/credits/) ·
|
|
217
218
|
MIT [License](https://github.com/jirikuncar/sqlty/blob/main/LICENSE).
|
|
218
219
|
|
|
@@ -23,13 +23,13 @@ migration that changes a column is caught in review, not in production.
|
|
|
23
23
|
(<a href="https://github.com/jirikuncar/sqlty/blob/main/docs/assets/demo.tape">view source</a>)
|
|
24
24
|
</p>
|
|
25
25
|
|
|
26
|
-
**Documentation: [
|
|
26
|
+
**Documentation: [sqlty.kuncar.dev](https://sqlty.kuncar.dev/)**
|
|
27
27
|
|
|
28
28
|
**Fits if** you write SQL as string literals on Python 3.14+, against
|
|
29
29
|
PostgreSQL, SQLite or MySQL, with a schema dump or SQL migrations in the
|
|
30
30
|
repository. Rows are typed end to end with psycopg 3; with other drivers sqlty
|
|
31
31
|
checks the query and its parameters, and you annotate what the cursor returns
|
|
32
|
-
([Drivers](https://
|
|
32
|
+
([Drivers](https://sqlty.kuncar.dev/guide/drivers-and-orms/)).
|
|
33
33
|
|
|
34
34
|
> **Beta.** APIs and configuration may change before 1.0. Feedback welcome in
|
|
35
35
|
> [GitHub Issues](https://github.com/jirikuncar/sqlty/issues).
|
|
@@ -91,10 +91,10 @@ query = SQL[tuple[int, str]]("--sql\nSELECT id, email FROM users")
|
|
|
91
91
|
caller that now needs a `None` check. `narrow-type` is an error, so CI fails on
|
|
92
92
|
it; an annotation that is only wider than the rows, such as `str | None` for a
|
|
93
93
|
column made `NOT NULL`, is a `stale-type` warning
|
|
94
|
-
([CI](https://
|
|
94
|
+
([CI](https://sqlty.kuncar.dev/recipes/ci/)). For rolling deploys,
|
|
95
95
|
`sqlty breaking --against origin/main` exits 1 when old code breaks on the new
|
|
96
96
|
schema or new code on the old one
|
|
97
|
-
([Breaking schema changes](https://
|
|
97
|
+
([Breaking schema changes](https://sqlty.kuncar.dev/guide/breaking-changes/)).
|
|
98
98
|
|
|
99
99
|
### A row type that doesn't match its query
|
|
100
100
|
|
|
@@ -111,7 +111,7 @@ query = SQL[User]("--sql\nSELECT id::INTEGER, name::TEXT FROM users")
|
|
|
111
111
|
```
|
|
112
112
|
|
|
113
113
|
`TypedDict`, `NamedTuple`, dataclasses and Pydantic models are all checked
|
|
114
|
-
([Row types](https://
|
|
114
|
+
([Row types](https://sqlty.kuncar.dev/guide/row-types/)).
|
|
115
115
|
|
|
116
116
|
### Wrong parameters, misspelled columns
|
|
117
117
|
|
|
@@ -143,11 +143,11 @@ conn.execute(SQL[tuple[str | None]]("--sql\nSELECT email FROM users WHERE id = ?
|
|
|
143
143
|
conn.execute("--sql\nSELECT emial FROM users")
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
-
`?`, `$1`, `%s` and `:name` placeholders are checked on sqlite3,
|
|
147
|
-
asyncpg calls ([Parameters](https://
|
|
146
|
+
`?`, `$1`, `%s` and `:name` placeholders are checked on sqlite3, aiosqlite,
|
|
147
|
+
psycopg and asyncpg calls ([Parameters](https://sqlty.kuncar.dev/guide/parameters/)).
|
|
148
148
|
These are the mistakes coding agents make: every problem is one
|
|
149
149
|
`file:line: [rule] message` line and a non-zero exit code they can act on, and
|
|
150
|
-
the [sqlty skills](https://
|
|
150
|
+
the [sqlty skills](https://sqlty.kuncar.dev/recipes/agents/) teach
|
|
151
151
|
them the conventions. In Claude Code, `/plugin install sqlty --marketplace jirikuncar/sqlty`
|
|
152
152
|
installs them.
|
|
153
153
|
|
|
@@ -163,13 +163,13 @@ sqlty strip . # undo: back to plain strings
|
|
|
163
163
|
|
|
164
164
|
`rewrite` and `strip` only touch the wrapper, never the SQL, so you can adopt
|
|
165
165
|
sqlty one module at a time and back out. New project:
|
|
166
|
-
[Quickstart](https://
|
|
167
|
-
[Migration](https://
|
|
166
|
+
[Quickstart](https://sqlty.kuncar.dev/quickstart/). Existing codebase:
|
|
167
|
+
[Migration](https://sqlty.kuncar.dev/recipes/migration/), starting
|
|
168
168
|
with `pg_dump --schema-only app > schema.sql`. In the editor:
|
|
169
|
-
[VS Code](https://
|
|
169
|
+
[VS Code](https://sqlty.kuncar.dev/recipes/vscode/).
|
|
170
170
|
|
|
171
171
|
Not a fit for ORMs, SQL built at runtime, or runtime validation;
|
|
172
|
-
[Why SQLTy?](https://
|
|
172
|
+
[Why SQLTy?](https://sqlty.kuncar.dev/motivation/) compares it with
|
|
173
173
|
sqlc, sqlx, PgTyped and others.
|
|
174
174
|
|
|
175
175
|
## About
|
|
@@ -180,5 +180,5 @@ developed with AI coding agents, mainly Claude Code; every change is reviewed by
|
|
|
180
180
|
a maintainer (see the
|
|
181
181
|
[AI-assisted contributions](https://github.com/jirikuncar/sqlty/blob/main/CONTRIBUTING.md#ai-assisted-contributions)
|
|
182
182
|
policy). [Contributing](https://github.com/jirikuncar/sqlty/blob/main/CONTRIBUTING.md) ·
|
|
183
|
-
[Credits](https://
|
|
183
|
+
[Credits](https://sqlty.kuncar.dev/credits/) ·
|
|
184
184
|
MIT [License](https://github.com/jirikuncar/sqlty/blob/main/LICENSE).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "sqlty"
|
|
3
3
|
dynamic = ["version"]
|
|
4
|
-
description = "Type-safe SQL
|
|
4
|
+
description = "Type-safe raw SQL for Python: row and parameter types inferred from your SQL and schema, no ORM or database needed"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.14"
|
|
7
7
|
license = "MIT"
|
|
@@ -9,11 +9,22 @@ license-files = ["LICENSE"]
|
|
|
9
9
|
authors = [{ name = "Jiri Kuncar", email = "jiri.kuncar@gmail.com" }]
|
|
10
10
|
keywords = [
|
|
11
11
|
"sql",
|
|
12
|
-
"
|
|
13
|
-
"mypy",
|
|
12
|
+
"raw-sql",
|
|
14
13
|
"type-safety",
|
|
14
|
+
"type-checking",
|
|
15
|
+
"type-hints",
|
|
15
16
|
"static-analysis",
|
|
17
|
+
"linter",
|
|
18
|
+
"mypy",
|
|
19
|
+
"pyright",
|
|
20
|
+
"ty",
|
|
21
|
+
"postgresql",
|
|
22
|
+
"sqlite",
|
|
23
|
+
"mysql",
|
|
24
|
+
"psycopg",
|
|
25
|
+
"migrations",
|
|
16
26
|
"code-generation",
|
|
27
|
+
"orm-alternative",
|
|
17
28
|
]
|
|
18
29
|
classifiers = [
|
|
19
30
|
"Development Status :: 4 - Beta",
|
|
@@ -27,6 +38,7 @@ classifiers = [
|
|
|
27
38
|
"Programming Language :: SQL",
|
|
28
39
|
"Topic :: Software Development :: Code Generators",
|
|
29
40
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
41
|
+
"Topic :: Software Development :: Quality Assurance",
|
|
30
42
|
"Topic :: Database",
|
|
31
43
|
"Typing :: Typed",
|
|
32
44
|
]
|
|
@@ -36,8 +48,8 @@ dependencies = [
|
|
|
36
48
|
]
|
|
37
49
|
|
|
38
50
|
[project.urls]
|
|
39
|
-
Homepage = "https://
|
|
40
|
-
Documentation = "https://
|
|
51
|
+
Homepage = "https://sqlty.kuncar.dev/"
|
|
52
|
+
Documentation = "https://sqlty.kuncar.dev/"
|
|
41
53
|
Repository = "https://github.com/jirikuncar/sqlty"
|
|
42
54
|
Changelog = "https://github.com/jirikuncar/sqlty/releases"
|
|
43
55
|
Issues = "https://github.com/jirikuncar/sqlty/issues"
|
|
@@ -45,6 +57,9 @@ Issues = "https://github.com/jirikuncar/sqlty/issues"
|
|
|
45
57
|
[project.scripts]
|
|
46
58
|
sqlty = "sqlty._cli:main"
|
|
47
59
|
|
|
60
|
+
[project.entry-points."pygments.lexers"]
|
|
61
|
+
sqlty = "sqlty.lexer:SQLTyLexer"
|
|
62
|
+
|
|
48
63
|
[project.optional-dependencies]
|
|
49
64
|
psycopg = ["psycopg>=3.2.12"]
|
|
50
65
|
|
|
@@ -83,11 +98,14 @@ dev = [
|
|
|
83
98
|
"pydantic[email]>=2.14.1",
|
|
84
99
|
"jsonschema>=4.26.0",
|
|
85
100
|
"pytest-xdist>=3.8.0",
|
|
101
|
+
"types-pygments>=2.19",
|
|
86
102
|
]
|
|
87
103
|
cli = ["rich>=15.0.0"]
|
|
88
104
|
# Only the DuckDB type tests need it, and it has no wheel for every Python.
|
|
89
105
|
duckdb = ["duckdb>=1.4.0"]
|
|
90
106
|
psycopg = ["psycopg>=3.2.12"]
|
|
107
|
+
# The aiosqlite calls sqlty checks, run against aiosqlite (tests/test_aiosqlite.py).
|
|
108
|
+
aiosqlite = ["aiosqlite>=0.22.1"]
|
|
91
109
|
fuzz = [
|
|
92
110
|
"hypothesis>=6.140",
|
|
93
111
|
]
|
|
@@ -1190,7 +1190,7 @@ dependencies = [
|
|
|
1190
1190
|
|
|
1191
1191
|
[[package]]
|
|
1192
1192
|
name = "sqlty-bench"
|
|
1193
|
-
version = "0.
|
|
1193
|
+
version = "0.5.1"
|
|
1194
1194
|
dependencies = [
|
|
1195
1195
|
"criterion",
|
|
1196
1196
|
"sqlty-python",
|
|
@@ -1199,7 +1199,7 @@ dependencies = [
|
|
|
1199
1199
|
|
|
1200
1200
|
[[package]]
|
|
1201
1201
|
name = "sqlty-core"
|
|
1202
|
-
version = "0.
|
|
1202
|
+
version = "0.5.1"
|
|
1203
1203
|
dependencies = [
|
|
1204
1204
|
"pyo3",
|
|
1205
1205
|
"recursive",
|
|
@@ -1214,7 +1214,7 @@ dependencies = [
|
|
|
1214
1214
|
|
|
1215
1215
|
[[package]]
|
|
1216
1216
|
name = "sqlty-format"
|
|
1217
|
-
version = "0.
|
|
1217
|
+
version = "0.5.1"
|
|
1218
1218
|
dependencies = [
|
|
1219
1219
|
"regex",
|
|
1220
1220
|
"sqlty-python",
|
|
@@ -1223,7 +1223,7 @@ dependencies = [
|
|
|
1223
1223
|
|
|
1224
1224
|
[[package]]
|
|
1225
1225
|
name = "sqlty-lsp"
|
|
1226
|
-
version = "0.
|
|
1226
|
+
version = "0.5.1"
|
|
1227
1227
|
dependencies = [
|
|
1228
1228
|
"crossbeam-channel",
|
|
1229
1229
|
"lsp-server",
|
|
@@ -1236,7 +1236,7 @@ dependencies = [
|
|
|
1236
1236
|
|
|
1237
1237
|
[[package]]
|
|
1238
1238
|
name = "sqlty-python"
|
|
1239
|
-
version = "0.
|
|
1239
|
+
version = "0.5.1"
|
|
1240
1240
|
dependencies = [
|
|
1241
1241
|
"regex",
|
|
1242
1242
|
"sqlty-sql",
|
|
@@ -1246,7 +1246,7 @@ dependencies = [
|
|
|
1246
1246
|
|
|
1247
1247
|
[[package]]
|
|
1248
1248
|
name = "sqlty-sql"
|
|
1249
|
-
version = "0.
|
|
1249
|
+
version = "0.5.1"
|
|
1250
1250
|
dependencies = [
|
|
1251
1251
|
"insta",
|
|
1252
1252
|
"recursive",
|
|
@@ -1260,7 +1260,7 @@ dependencies = [
|
|
|
1260
1260
|
|
|
1261
1261
|
[[package]]
|
|
1262
1262
|
name = "sqlty-wasm"
|
|
1263
|
-
version = "0.
|
|
1263
|
+
version = "0.5.1"
|
|
1264
1264
|
dependencies = [
|
|
1265
1265
|
"serde",
|
|
1266
1266
|
"serde_json",
|
|
@@ -3,13 +3,13 @@ resolver = "2"
|
|
|
3
3
|
members = ["crates/*"]
|
|
4
4
|
|
|
5
5
|
[workspace.package]
|
|
6
|
-
version = "0.
|
|
6
|
+
version = "0.5.1"
|
|
7
7
|
edition = "2021"
|
|
8
8
|
description = "Rust engine of sqlty: SQL type inference and Python source rewriting"
|
|
9
9
|
license = "MIT"
|
|
10
10
|
repository = "https://github.com/jirikuncar/sqlty"
|
|
11
11
|
publish = false
|
|
12
|
-
rust-version = "1.
|
|
12
|
+
rust-version = "1.99"
|
|
13
13
|
|
|
14
14
|
[workspace.dependencies]
|
|
15
15
|
pyo3 = { version = "0.30", features = ["extension-module"] }
|
|
@@ -180,6 +180,15 @@ impl SchemaHandle {
|
|
|
180
180
|
self.dialect
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
/// Whether queries of this database are read without a schema: it was loaded without one.
|
|
184
|
+
#[getter]
|
|
185
|
+
fn absent(&self) -> bool {
|
|
186
|
+
self.loaded
|
|
187
|
+
.schema
|
|
188
|
+
.databases()
|
|
189
|
+
.is_some_and(|databases| databases.absent)
|
|
190
|
+
}
|
|
191
|
+
|
|
183
192
|
fn __repr__(&self) -> String {
|
|
184
193
|
format!("Schema(dialect={:?})", self.dialect)
|
|
185
194
|
}
|
|
@@ -190,15 +199,24 @@ impl SchemaHandle {
|
|
|
190
199
|
/// `types` maps a SQL type name (`DATE`) or a `table.column` to the Python type a
|
|
191
200
|
/// converter above the driver gives it (`[tool.sqlty.types]`).
|
|
192
201
|
///
|
|
202
|
+
/// `databases` maps the name of each other database of the project to its schema, `None`
|
|
203
|
+
/// for one without; a query whose marker names one (`--sql sqlty:db=analytics`) is read
|
|
204
|
+
/// against it, in its dialect. `name` is this database's, and `absent` says it has no
|
|
205
|
+
/// schema: its queries are read without one.
|
|
206
|
+
///
|
|
193
207
|
/// Raises:
|
|
194
208
|
/// ValueError: a key of `types` is neither a SQL type nor `table.column`
|
|
195
209
|
#[pyfunction]
|
|
196
|
-
#[pyo3(signature = (schema_sql, *, dialect = DialectArg::POSTGRES, types = None))]
|
|
210
|
+
#[pyo3(signature = (schema_sql, *, dialect = DialectArg::POSTGRES, types = None, name = None, absent = false, databases = None))]
|
|
211
|
+
#[allow(clippy::too_many_arguments)]
|
|
197
212
|
fn load_schema(
|
|
198
213
|
py: Python<'_>,
|
|
199
214
|
schema_sql: &str,
|
|
200
215
|
dialect: DialectArg,
|
|
201
216
|
types: Option<Vec<(String, String)>>,
|
|
217
|
+
name: Option<String>,
|
|
218
|
+
absent: bool,
|
|
219
|
+
databases: Option<Vec<(String, Option<PyRef<'_, SchemaHandle>>)>>,
|
|
202
220
|
) -> PyResult<SchemaHandle> {
|
|
203
221
|
let dialect = dialect.0;
|
|
204
222
|
let overrides = analyzer::TypeOverrides::new(&types.unwrap_or_default(), dialect)
|
|
@@ -211,6 +229,33 @@ fn load_schema(
|
|
|
211
229
|
};
|
|
212
230
|
Arc::new(LoadedSchema { schema, skipped })
|
|
213
231
|
});
|
|
232
|
+
let loaded = match databases {
|
|
233
|
+
None if name.is_none() && !absent => loaded,
|
|
234
|
+
databases => {
|
|
235
|
+
let others = databases
|
|
236
|
+
.unwrap_or_default()
|
|
237
|
+
.into_iter()
|
|
238
|
+
.map(|(other, handle)| match handle {
|
|
239
|
+
Some(handle) => (
|
|
240
|
+
other,
|
|
241
|
+
handle.dialect,
|
|
242
|
+
(!handle.absent()).then(|| handle.loaded.schema.clone()),
|
|
243
|
+
),
|
|
244
|
+
None => (other, dialect, None),
|
|
245
|
+
})
|
|
246
|
+
.collect();
|
|
247
|
+
let databases = analyzer::Databases {
|
|
248
|
+
name: name.unwrap_or_else(|| analyzer::DEFAULT.to_string()),
|
|
249
|
+
absent,
|
|
250
|
+
others,
|
|
251
|
+
};
|
|
252
|
+
let LoadedSchema { schema, skipped } =
|
|
253
|
+
Arc::into_inner(loaded).expect("a schema just loaded is not shared");
|
|
254
|
+
let schema = analyzer::SchemaData::with_databases(schema, databases)
|
|
255
|
+
.expect("a schema just loaded is not shared");
|
|
256
|
+
Arc::new(LoadedSchema { schema, skipped })
|
|
257
|
+
}
|
|
258
|
+
};
|
|
214
259
|
Ok(SchemaHandle {
|
|
215
260
|
loaded,
|
|
216
261
|
text: Arc::from(schema_sql),
|
|
@@ -14,4 +14,6 @@ workspace = true
|
|
|
14
14
|
[dependencies]
|
|
15
15
|
sqlty-python.workspace = true
|
|
16
16
|
regex.workspace = true
|
|
17
|
+
# On upgrade, check quarylabs/sqruff#5251: 0.44 lays out a query only up to an unparsable
|
|
18
|
+
# `{name}` field. Once fixed, drop the `\{\w*\}` arm of `PLACEHOLDER` in src/lib.rs.
|
|
17
19
|
sqruff-lib = "0.44"
|
|
@@ -32,10 +32,10 @@ use sqlty_python::rewriter::ImportStyle;
|
|
|
32
32
|
use sqruff_lib::core::config::FluffConfig;
|
|
33
33
|
use sqruff_lib::core::linter::core::Linter;
|
|
34
34
|
|
|
35
|
-
/// psycopg's `%s`, `%(name)s` and `%%`,
|
|
36
|
-
/// sqruff does not read as values.
|
|
35
|
+
/// psycopg's `%s`, `%(name)s` and `%%`, the `?` of SQLite and MySQL drivers, and the `{name}`
|
|
36
|
+
/// fields of `str.format` and `sql.SQL` templates, which sqruff does not read as values.
|
|
37
37
|
static PLACEHOLDER: LazyLock<Regex> =
|
|
38
|
-
LazyLock::new(|| Regex::new(r"%(?:\([^)]*\))?[sbt]
|
|
38
|
+
LazyLock::new(|| Regex::new(r"%(?:\([^)]*\))?[sbt]|%%|\?|\{\w*\}").unwrap());
|
|
39
39
|
|
|
40
40
|
/// `source` with every query string sqruff can lay out formatted in `dialect`.
|
|
41
41
|
pub fn format_source(source: &str, dialect: &str, style: &ImportStyle) -> String {
|
|
@@ -13,7 +13,7 @@ use crate::text::LineIndex;
|
|
|
13
13
|
use crate::{Diagnostic, Document, Severity};
|
|
14
14
|
|
|
15
15
|
/// The rules reference; each rule is a heading of it.
|
|
16
|
-
const RULES: &str = "https://
|
|
16
|
+
const RULES: &str = "https://sqlty.kuncar.dev/reference/rules/";
|
|
17
17
|
|
|
18
18
|
pub(crate) fn diagnostic(diagnostic: &Diagnostic, index: &LineIndex<'_>) -> lsp_types::Diagnostic {
|
|
19
19
|
lsp_types::Diagnostic {
|
|
@@ -261,7 +261,7 @@ fn diagnostics_are_published_in_utf16_units() {
|
|
|
261
261
|
assert_eq!(diagnostic["severity"], 1);
|
|
262
262
|
assert_eq!(
|
|
263
263
|
diagnostic["codeDescription"]["href"],
|
|
264
|
-
"https://
|
|
264
|
+
"https://sqlty.kuncar.dev/reference/rules/#stale-type"
|
|
265
265
|
);
|
|
266
266
|
client.shutdown();
|
|
267
267
|
}
|
|
@@ -27,7 +27,9 @@ use crate::rewriter::{
|
|
|
27
27
|
use crate::rules::{Rule, RuleConfig, Severity};
|
|
28
28
|
use crate::scan::Scan;
|
|
29
29
|
use crate::tokens::{content, query_offset, Call};
|
|
30
|
-
use sqlty_sql::analyzer::{
|
|
30
|
+
use sqlty_sql::analyzer::{
|
|
31
|
+
expand_star, parse, route, row_type, unknown_database, Column, Parsed, SchemaData,
|
|
32
|
+
};
|
|
31
33
|
use sqlty_sql::diagnostics::{NameDiagnostic, NameRule};
|
|
32
34
|
use std::ops::Range;
|
|
33
35
|
|
|
@@ -231,8 +233,9 @@ impl Checker<'_> {
|
|
|
231
233
|
}
|
|
232
234
|
#[cfg(test)]
|
|
233
235
|
ANALYZED.with(|count| count.set(count.get() + 1));
|
|
234
|
-
let
|
|
235
|
-
let
|
|
236
|
+
let (dialect, schema) = route(query, self.options.dialect.name(), self.options.schema);
|
|
237
|
+
let parsed = parse(query, dialect);
|
|
238
|
+
let (columns, diagnostics) = parsed.analyze_with_diagnostics(schema);
|
|
236
239
|
let columns = columns.ok().flatten();
|
|
237
240
|
let analysis = Rc::new(Analysis {
|
|
238
241
|
row_type: columns.as_deref().and_then(row_type),
|
|
@@ -428,6 +431,11 @@ impl Checker<'_> {
|
|
|
428
431
|
fix.into_iter().collect(),
|
|
429
432
|
);
|
|
430
433
|
}
|
|
434
|
+
if let Some(message) = marked_query(sql_content)
|
|
435
|
+
.and_then(|query| unknown_database(&query, self.options.schema))
|
|
436
|
+
{
|
|
437
|
+
self.report(Rule::UnknownDatabase, message, at);
|
|
438
|
+
}
|
|
431
439
|
if self.rules.is_enabled(Rule::UnparsedQuery) && !template {
|
|
432
440
|
if let Some(error) =
|
|
433
441
|
marked_query(sql_content).and_then(|sql| self.analysis(&sql).parsed.error())
|
|
@@ -515,18 +523,14 @@ impl Checker<'_> {
|
|
|
515
523
|
return;
|
|
516
524
|
};
|
|
517
525
|
let stars = self.analysis(&query).parsed.result_stars();
|
|
518
|
-
let
|
|
519
|
-
else {
|
|
526
|
+
let (dialect, schema) = route(&query, self.options.dialect.name(), self.options.schema);
|
|
527
|
+
let Some((rule, message)) = star_finding(stars, &query, schema.is_some()) else {
|
|
520
528
|
return;
|
|
521
529
|
};
|
|
522
|
-
let fix = match (rule, call.strings.as_slice(),
|
|
523
|
-
(Rule::SelectStar, [span], Some(schema)) =>
|
|
524
|
-
self.scan.source(),
|
|
525
|
-
|
|
526
|
-
sql_content,
|
|
527
|
-
self.options.dialect.name(),
|
|
528
|
-
schema,
|
|
529
|
-
),
|
|
530
|
+
let fix = match (rule, call.strings.as_slice(), schema) {
|
|
531
|
+
(Rule::SelectStar, [span], Some(schema)) => {
|
|
532
|
+
expanded_literal(self.scan.source(), span, sql_content, dialect, schema)
|
|
533
|
+
}
|
|
530
534
|
_ => None,
|
|
531
535
|
};
|
|
532
536
|
self.report_fix(rule, message, at, fix.into_iter().collect());
|
|
@@ -541,10 +545,11 @@ impl Checker<'_> {
|
|
|
541
545
|
/// Why a query has no row type, and what to do about it: the first name or construct
|
|
542
546
|
/// the analyzer could not type, else the untyped columns.
|
|
543
547
|
fn untyped_cause(&self, sql_content: &str) -> String {
|
|
544
|
-
let has_schema = self.options.schema.is_some_and(|schema| !schema.is_empty());
|
|
545
548
|
let Some(query) = marked_query(sql_content) else {
|
|
546
549
|
return "add casts (for example id::INTEGER) or a schema".to_string();
|
|
547
550
|
};
|
|
551
|
+
let (_, schema) = route(&query, self.options.dialect.name(), self.options.schema);
|
|
552
|
+
let has_schema = schema.is_some_and(|schema| !schema.is_empty());
|
|
548
553
|
let analysis = self.analysis(&query);
|
|
549
554
|
if let Some(diagnostic) = analysis.diagnostics.first() {
|
|
550
555
|
let hint = match diagnostic.rule {
|
|
@@ -719,8 +724,12 @@ fn expanded_literal(
|
|
|
719
724
|
}
|
|
720
725
|
|
|
721
726
|
/// A `--sql` marker line at the start of string content.
|
|
722
|
-
static SQL_PREFIX: LazyLock<Regex> =
|
|
723
|
-
|
|
727
|
+
static SQL_PREFIX: LazyLock<Regex> = LazyLock::new(|| {
|
|
728
|
+
Regex::new(
|
|
729
|
+
r"(?s)^(\s*(?:--sql|-- sql)(?:[ \t]+sqlty:[ \t]*db=[\w-]+)?(?:\\r\\n|\\n|\r?\n))(.*)",
|
|
730
|
+
)
|
|
731
|
+
.unwrap()
|
|
732
|
+
});
|
|
724
733
|
|
|
725
734
|
const INLINE_MESSAGE: &str = r#""--sql SELECT ..." treats the query as a SQL comment; use "--sql\nSELECT ..." or run sqlty check --fix"#;
|
|
726
735
|
|