execsql2 2.21.1__tar.gz → 2.21.2__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.
- {execsql2-2.21.1 → execsql2-2.21.2}/.github/workflows/ci-cd.yml +13 -13
- {execsql2-2.21.1 → execsql2-2.21.2}/CHANGELOG.md +8 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/PKG-INFO +2 -2
- {execsql2-2.21.1 → execsql2-2.21.2}/README.md +1 -1
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/guides/formatter.md +1 -1
- {execsql2-2.21.1 → execsql2-2.21.2}/pyproject.toml +2 -2
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/feather.py +1 -1
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/parquet.py +1 -1
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_postgres.py +46 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_parquet.py +8 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/integration/test_postgres.py +51 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/uv.lock +1 -1
- {execsql2-2.21.1 → execsql2-2.21.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/.github/dependabot.yml +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/.gitignore +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/.pre-commit-config.yaml +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/.pre-commit-hooks.yaml +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/.python-version +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/.readthedocs.yaml +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/CONTRIBUTING.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/LICENSE.txt +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/NOTICE +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/SECURITY.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/about/contributors.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/about/copyright.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/about/divergence.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/api/cli.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/api/db.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/api/exporters.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/api/importers.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/api/index.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/api/metacommands.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/dev/adding_db_adapters.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/dev/adding_exporters.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/dev/adding_importers.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/dev/adding_metacommands.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/dev/architecture.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/dev/releasing.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/getting-started/installation.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/getting-started/requirements.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/getting-started/syntax.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/guides/debugging.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/guides/documentation.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/guides/encoding.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/guides/examples.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/guides/logging.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/guides/sql_syntax.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/guides/usage.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/guides/using_scripts.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/Compare_planets.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/actions.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/actions2.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/checkboxes.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/connect.b64 +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/connect.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/create_conf.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/data_error1_screenshot.jpg +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/entry_form.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/execsql_console.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/execsql_logo_01.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/fatals.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/logo_small.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/pause_terminal.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/pause_terminal_sm.b64 +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/pause_terminal_sm.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/prompt_compare.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/set_build_commands.jpg +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/unit_conversions.b64 +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/unit_conversions_029.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/unmatched.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/images/vim_execsql_highlight.png +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/index.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/reference/configuration.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/reference/metacommands.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/reference/security.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/docs/reference/substitution_vars.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/extras/plugin-template/README.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/extras/plugin-template/pyproject.toml +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/extras/plugin-template/src/execsql_plugin_YOURNAME/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/extras/plugin-template/tests/test_plugin.py.example +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/extras/vscode-execsql/README.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/extras/vscode-execsql/package.json +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/extras/vscode-execsql/syntaxes/execsql.tmLanguage.json +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/justfile +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/scripts/generate_vscode_grammar.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/__main__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/api.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/cli/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/cli/dsn.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/cli/help.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/cli/lint.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/cli/run.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/config.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/data/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/data/execsql.conf.template +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/access.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/base.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/dsn.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/duckdb.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/factory.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/firebird.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/mysql.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/oracle.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/postgres.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/sqlite.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/db/sqlserver.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/debug/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/debug/repl.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exceptions.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/base.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/delimited.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/duckdb.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/html.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/json.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/latex.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/markdown.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/ods.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/pretty.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/protocol.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/raw.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/sqlite.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/templates.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/values.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/xls.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/xlsx.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/xml.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/yaml.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/exporters/zip.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/format.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/gui/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/gui/base.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/gui/console.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/gui/desktop.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/gui/tui.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/importers/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/importers/base.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/importers/csv.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/importers/feather.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/importers/json.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/importers/ods.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/importers/xls.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/conditions.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/connect.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/control.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/data.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/debug.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/dispatch.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/io.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/io_export.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/io_fileops.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/io_import.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/io_write.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/prompt.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/script_ext.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/system.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/metacommands/upsert.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/models.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/parser.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/plugins.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/py.typed +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/script/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/script/ast.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/script/control.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/script/engine.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/script/executor.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/script/parser.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/script/variables.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/state.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/types.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/auth.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/crypto.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/datetime.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/errors.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/fileio.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/gui.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/mail.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/numeric.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/regex.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/strings.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/src/execsql/utils/timer.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/README.md +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/config_settings.sqlite +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/example_config_prompt.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/make_config_db.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/md_compare.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/md_glossary.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/md_upsert.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/pg_compare.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/pg_glossary.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/pg_upsert.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/script_template.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/ss_compare.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/ss_glossary.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/templates/ss_upsert.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/cli/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/cli/test_cli.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/cli/test_cli_e2e.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/cli/test_cli_run.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/cli/test_lint.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/cli/test_ping.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/cli/test_profile.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/conftest.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_access_windows.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_base.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_db_adapters_mocked.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_db_adapters_mocked_extra.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_dsn.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_duckdb.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_factory.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_mysql_case_folding.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_mysql_inprocess.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_postgres_inprocess.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_sqlite.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_sqlite_extra.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/db/test_sqlserver_inprocess.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_base.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_db.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_delimited.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_duckdb_exporter.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_exporters.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_feather.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_html_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_html_latex.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_json.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_json_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_latex_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_markdown.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_ods.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_ods_export.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_pretty_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_raw_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_sqlite_exporter.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_templates.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_templates_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_values_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_xls_xlsx.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_xlsx.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_xml.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_yaml.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/exporters/test_zip.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/gui/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/gui/test_backends.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/gui/test_backends_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/gui/test_compare_stats.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/gui/test_compute_row_diffs.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/gui/test_desktop_dialogs.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/gui/test_tui_pilot.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/gui/test_tui_pilot_complex.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/gui/test_utils_gui_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/importers/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/importers/test_base_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/importers/test_csv_edge_cases.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/importers/test_csv_importer.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/importers/test_feather_importer.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/importers/test_json_importer.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/importers/test_ods_importer.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/importers/test_xls_importer.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/integration/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/integration/conftest.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/integration/test_dsn.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/integration/test_duckdb.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/integration/test_mysql.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/integration/test_sqlite.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_assert.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_breakpoint.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_conditions_extra.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_connect.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_io_export.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_io_import.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_metacommands.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_metacommands_connect.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_metacommands_data.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_metacommands_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_metacommands_fileops_extra.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_metacommands_io.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_metacommands_io_write_extra.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_metacommands_script_ext.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_metacommands_system.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_metacommands_system_extra.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_pg_upsert.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_prompt.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_row_count.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/metacommands/test_show_scripts.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/audit_lint_bad.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/audit_smoke/sample.json +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/audit_smoke/sample.jsonl +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/audit_smoke.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/config_runtime.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/control_flow.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/counters_and_locals.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/error_handling.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/import_options/has_comments.csv +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/import_options.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/includes/helper.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/includes.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/io_formats.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/io_roundtrip.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/multi_db.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/parquet_feather_roundtrip.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/parse_only/parse_tree.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/predicates.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/scripts.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/smoke.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/subroutine_loops.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/subvars_advanced.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/template_export/greeting.tmpl +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/template_export.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/timer.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/transactions.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/write_create_table.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/fixtures/xlsx_ods_roundtrip.sql +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/scripts/test_sql_scripts.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/security/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/security/test_env_detection.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/security/test_expansion_bomb.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/security/test_import_regex_hardening.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/security/test_log_redaction.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/security/test_odbc_injection.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/security/test_path_containment.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/security/test_substitution_injection.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/security/test_zip_bomb.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_api.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_api_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_ast.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_ast_parser.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_bundled_templates.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_config.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_config_data.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_config_extended.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_debug_repl.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_engine.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_error_messages.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_exceptions.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_executor.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_executor_inprocess.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_format.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_mail.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_models.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_package.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_parser.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_parser_params.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_plugins.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_registry.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_script.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_state.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/test_types.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/__init__.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_auth.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_auth_extra.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_crypto.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_datetime.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_encodedfile_context.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_errors.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_errors_extra.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_fileio.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_fileio_extra.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_numeric.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_regex.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_strings.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_timer.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/tests/utils/test_timer_extra.py +0 -0
- {execsql2-2.21.1 → execsql2-2.21.2}/zensical.toml +0 -0
|
@@ -20,8 +20,8 @@ jobs:
|
|
|
20
20
|
permissions:
|
|
21
21
|
contents: read
|
|
22
22
|
steps:
|
|
23
|
-
- uses: actions/checkout@
|
|
24
|
-
- uses: actions/setup-python@
|
|
23
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
24
|
+
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
|
25
25
|
with:
|
|
26
26
|
python-version: "3.13"
|
|
27
27
|
- run: python -m pip install ruff
|
|
@@ -48,13 +48,13 @@ jobs:
|
|
|
48
48
|
contents: read
|
|
49
49
|
steps:
|
|
50
50
|
- name: Check out repository code
|
|
51
|
-
uses: actions/checkout@
|
|
51
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
52
52
|
- name: Setup Python ${{ matrix.python-version }}
|
|
53
|
-
uses: actions/setup-python@
|
|
53
|
+
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
|
54
54
|
with:
|
|
55
55
|
python-version: ${{ matrix.python-version }}
|
|
56
56
|
- name: Cache pip dependencies
|
|
57
|
-
uses: actions/cache@
|
|
57
|
+
uses: actions/cache@2c8a9bd7457de244a408f35966fab2fb45fda9c8 # v6.0.0
|
|
58
58
|
with:
|
|
59
59
|
path: ~/.cache/pip
|
|
60
60
|
key: ${{ runner.os }}-pip-${{ matrix.python-version }}-${{
|
|
@@ -139,9 +139,9 @@ jobs:
|
|
|
139
139
|
--health-interval 10s --health-timeout 5s --health-retries 20
|
|
140
140
|
steps:
|
|
141
141
|
- name: Check out repository code
|
|
142
|
-
uses: actions/checkout@
|
|
142
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
143
143
|
- name: Setup Python ${{ matrix.python-version }}
|
|
144
|
-
uses: actions/setup-python@
|
|
144
|
+
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
|
145
145
|
with:
|
|
146
146
|
python-version: ${{ matrix.python-version }}
|
|
147
147
|
- name: Install tkinter (Ubuntu)
|
|
@@ -187,8 +187,8 @@ jobs:
|
|
|
187
187
|
permissions:
|
|
188
188
|
contents: read
|
|
189
189
|
steps:
|
|
190
|
-
- uses: actions/checkout@
|
|
191
|
-
- uses: actions/setup-python@
|
|
190
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
191
|
+
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
|
192
192
|
with:
|
|
193
193
|
python-version: ${{ matrix.python-version }}
|
|
194
194
|
- name: Install Microsoft Access Database Engine 2016 (x64)
|
|
@@ -238,9 +238,9 @@ jobs:
|
|
|
238
238
|
permissions:
|
|
239
239
|
contents: read
|
|
240
240
|
steps:
|
|
241
|
-
- uses: actions/checkout@
|
|
241
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
242
242
|
- name: Set up Python
|
|
243
|
-
uses: actions/setup-python@
|
|
243
|
+
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
|
|
244
244
|
with:
|
|
245
245
|
python-version: "3.13"
|
|
246
246
|
cache: "pip"
|
|
@@ -288,14 +288,14 @@ jobs:
|
|
|
288
288
|
contents: write
|
|
289
289
|
steps:
|
|
290
290
|
- name: Checkout
|
|
291
|
-
uses: actions/checkout@
|
|
291
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
|
|
292
292
|
- name: Download dist
|
|
293
293
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
294
294
|
with:
|
|
295
295
|
name: ${{ github.event.repository.name }}
|
|
296
296
|
path: dist/
|
|
297
297
|
- name: Create release
|
|
298
|
-
uses: softprops/action-gh-release@
|
|
298
|
+
uses: softprops/action-gh-release@718ea10b132b3b2eba29c1007bb80653f286566b # v3.0.1
|
|
299
299
|
with:
|
|
300
300
|
draft: false
|
|
301
301
|
prerelease: false
|
|
@@ -13,6 +13,14 @@ ______________________________________________________________________
|
|
|
13
13
|
|
|
14
14
|
______________________________________________________________________
|
|
15
15
|
|
|
16
|
+
## [2.21.2] - 2026-06-30
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- Fixed `EXPORT … AS PARQUET` and `EXPORT … AS FEATHER` `ComputeError` when a result column has more than 100 leading `NULL` values followed by non-null numeric values.
|
|
21
|
+
|
|
22
|
+
______________________________________________________________________
|
|
23
|
+
|
|
16
24
|
## [2.21.1] - 2026-06-24
|
|
17
25
|
|
|
18
26
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: execsql2
|
|
3
|
-
Version: 2.21.
|
|
3
|
+
Version: 2.21.2
|
|
4
4
|
Summary: Runs a SQL script against a PostgreSQL, SQLite, MariaDB/MySQL, DuckDB, Firebird, MS-Access, MS-SQL-Server, or Oracle database, or an ODBC DSN. Provides metacommands to import and export data, copy data between databases, conditionally execute SQL and metacommands, and dynamically alter SQL and metacommands with substitution variables.
|
|
5
5
|
Project-URL: Homepage, https://execsql2.readthedocs.io
|
|
6
6
|
Project-URL: Repository, https://github.com/geocoug/execsql
|
|
@@ -403,7 +403,7 @@ execsql-format --no-sql --in-place scripts/
|
|
|
403
403
|
```yaml
|
|
404
404
|
repos:
|
|
405
405
|
- repo: https://github.com/geocoug/execsql
|
|
406
|
-
rev: v2.21.
|
|
406
|
+
rev: v2.21.2
|
|
407
407
|
hooks:
|
|
408
408
|
- id: execsql-format
|
|
409
409
|
```
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "execsql2"
|
|
7
|
-
version = "2.21.
|
|
7
|
+
version = "2.21.2"
|
|
8
8
|
description = "Runs a SQL script against a PostgreSQL, SQLite, MariaDB/MySQL, DuckDB, Firebird, MS-Access, MS-SQL-Server, or Oracle database, or an ODBC DSN. Provides metacommands to import and export data, copy data between databases, conditionally execute SQL and metacommands, and dynamically alter SQL and metacommands with substitution variables."
|
|
9
9
|
readme = { file = "README.md", content-type = "text/markdown" }
|
|
10
10
|
license = { file = "LICENSE.txt" }
|
|
@@ -178,7 +178,7 @@ skip-magic-trailing-comma = false
|
|
|
178
178
|
line-ending = "auto"
|
|
179
179
|
|
|
180
180
|
[tool.bumpversion]
|
|
181
|
-
current_version = "2.21.
|
|
181
|
+
current_version = "2.21.2"
|
|
182
182
|
commit = true
|
|
183
183
|
tag = true
|
|
184
184
|
tag_name = "v{new_version}"
|
|
@@ -33,7 +33,7 @@ def write_query_to_feather(outfile: str, headers: list[str], rows: Any) -> None:
|
|
|
33
33
|
) from e
|
|
34
34
|
rows_list = list(rows)
|
|
35
35
|
if rows_list:
|
|
36
|
-
df = pl.DataFrame(rows_list, schema=headers, orient="row")
|
|
36
|
+
df = pl.DataFrame(rows_list, schema=headers, orient="row", infer_schema_length=None)
|
|
37
37
|
else:
|
|
38
38
|
df = pl.DataFrame({h: [] for h in headers})
|
|
39
39
|
filewriter_close(outfile)
|
|
@@ -28,7 +28,7 @@ def write_query_to_parquet(outfile: str, headers: list[str], rows: Any) -> None:
|
|
|
28
28
|
) from e
|
|
29
29
|
rows_list = list(rows)
|
|
30
30
|
if rows_list:
|
|
31
|
-
df = pl.DataFrame(rows_list, schema=headers, orient="row")
|
|
31
|
+
df = pl.DataFrame(rows_list, schema=headers, orient="row", infer_schema_length=None)
|
|
32
32
|
else:
|
|
33
33
|
df = pl.DataFrame({h: [] for h in headers})
|
|
34
34
|
filewriter_close(outfile)
|
|
@@ -93,3 +93,49 @@ class TestPostgresConnectTimeout:
|
|
|
93
93
|
# Credential-less path still uses ``dbname``.
|
|
94
94
|
assert call_kwargs["dbname"] == "testdb"
|
|
95
95
|
assert "database" not in call_kwargs
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# ---------------------------------------------------------------------------
|
|
99
|
+
# Regression: psycopg3 auto-prepared statements must stay disabled
|
|
100
|
+
#
|
|
101
|
+
# psycopg3 promotes a query to a server-side prepared statement after the same
|
|
102
|
+
# query text runs ``prepare_threshold`` times (default 5). Scripts that re-run
|
|
103
|
+
# a query (e.g. via EXPORT) against an object they drop/recreate or alter then
|
|
104
|
+
# hit "cached plan must not change result type". psycopg2 never auto-prepared,
|
|
105
|
+
# so the adapter passes ``prepare_threshold=None`` to restore that behavior.
|
|
106
|
+
# ---------------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class TestPostgresPrepareThresholdDisabled:
|
|
110
|
+
@patch.dict("sys.modules", {"psycopg": _make_mock_psycopg()})
|
|
111
|
+
def test_prepare_threshold_disabled_with_credentials(self):
|
|
112
|
+
import sys
|
|
113
|
+
|
|
114
|
+
mock_psycopg = sys.modules["psycopg"]
|
|
115
|
+
from execsql.db.postgres import PostgresDatabase
|
|
116
|
+
|
|
117
|
+
PostgresDatabase(
|
|
118
|
+
server_name="localhost",
|
|
119
|
+
db_name="testdb",
|
|
120
|
+
user_name="user",
|
|
121
|
+
password="pass",
|
|
122
|
+
)
|
|
123
|
+
call_kwargs = mock_psycopg.connect.call_args[1]
|
|
124
|
+
assert "prepare_threshold" in call_kwargs
|
|
125
|
+
assert call_kwargs["prepare_threshold"] is None
|
|
126
|
+
|
|
127
|
+
@patch.dict("sys.modules", {"psycopg": _make_mock_psycopg()})
|
|
128
|
+
def test_prepare_threshold_disabled_without_credentials(self):
|
|
129
|
+
import sys
|
|
130
|
+
|
|
131
|
+
mock_psycopg = sys.modules["psycopg"]
|
|
132
|
+
from execsql.db.postgres import PostgresDatabase
|
|
133
|
+
|
|
134
|
+
PostgresDatabase(
|
|
135
|
+
server_name="localhost",
|
|
136
|
+
db_name="testdb",
|
|
137
|
+
user_name=None,
|
|
138
|
+
)
|
|
139
|
+
call_kwargs = mock_psycopg.connect.call_args[1]
|
|
140
|
+
assert "prepare_threshold" in call_kwargs
|
|
141
|
+
assert call_kwargs["prepare_threshold"] is None
|
|
@@ -60,3 +60,11 @@ class TestWriteQueryToParquet:
|
|
|
60
60
|
assert len(result["id"]) == 100
|
|
61
61
|
assert result["id"][0] == 0
|
|
62
62
|
assert result["label"][99] == "item_99"
|
|
63
|
+
|
|
64
|
+
def test_leading_nulls_then_float(self, noop_filewriter_close, tmp_path):
|
|
65
|
+
out = str(tmp_path / "out.parquet")
|
|
66
|
+
rows = [(None,)] * 100 + [(12.5,), (5.2,)]
|
|
67
|
+
write_query_to_parquet(out, ["val"], iter(rows))
|
|
68
|
+
result = pl.read_parquet(out).to_dict(as_series=False)
|
|
69
|
+
assert result["val"][100] == pytest.approx(12.5)
|
|
70
|
+
assert result["val"][101] == pytest.approx(5.2)
|
|
@@ -412,3 +412,54 @@ class TestExportJSON:
|
|
|
412
412
|
assert data[1]["label"] == "beta"
|
|
413
413
|
|
|
414
414
|
_exec_pg("DROP TABLE IF EXISTS items")
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
# ---------------------------------------------------------------------------
|
|
418
|
+
# Regression: psycopg3 cached-plan / auto-prepared statements
|
|
419
|
+
#
|
|
420
|
+
# psycopg3 promotes a query to a server-side prepared statement after the same
|
|
421
|
+
# query text runs prepare_threshold times (default 5). Re-EXPORTing a view that
|
|
422
|
+
# the script drops/recreates with a different result type used to raise
|
|
423
|
+
# "FeatureNotSupported: cached plan must not change result type". The adapter
|
|
424
|
+
# now connects with prepare_threshold=None; this exercises the full pipeline to
|
|
425
|
+
# prove the fix end-to-end. See CHANGELOG 2.21.1.
|
|
426
|
+
# ---------------------------------------------------------------------------
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
class TestCachedPlanRegression:
|
|
430
|
+
def test_repeated_export_after_view_result_type_change(self, tmp_path):
|
|
431
|
+
"""EXPORT the same view past the prepare threshold, then recreate it with
|
|
432
|
+
a different column type and EXPORT again — must not error."""
|
|
433
|
+
_exec_pg("DROP VIEW IF EXISTS val_summ")
|
|
434
|
+
_exec_pg("DROP TABLE IF EXISTS val_src")
|
|
435
|
+
_write_conf(tmp_path)
|
|
436
|
+
out = tmp_path / "summ.txt"
|
|
437
|
+
|
|
438
|
+
# Six exports of identical query text cross psycopg3's default
|
|
439
|
+
# prepare_threshold (5); the view is then recreated returning a TEXT
|
|
440
|
+
# column instead of an INTEGER one and exported again.
|
|
441
|
+
first_exports = "\n".join(f"-- !x! EXPORT val_summ TO {out} AS TXT" for _ in range(6))
|
|
442
|
+
second_exports = "\n".join(f"-- !x! EXPORT val_summ TO {out} AS TXT" for _ in range(6))
|
|
443
|
+
script = write_script(
|
|
444
|
+
tmp_path,
|
|
445
|
+
f"""\
|
|
446
|
+
CREATE TABLE val_src (id INTEGER, name TEXT);
|
|
447
|
+
INSERT INTO val_src VALUES (1, 'alpha');
|
|
448
|
+
|
|
449
|
+
CREATE VIEW val_summ AS SELECT id AS c FROM val_src;
|
|
450
|
+
{first_exports}
|
|
451
|
+
|
|
452
|
+
DROP VIEW val_summ;
|
|
453
|
+
CREATE VIEW val_summ AS SELECT name AS c FROM val_src;
|
|
454
|
+
{second_exports}
|
|
455
|
+
""",
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
result = _run_execsql_pg(tmp_path, script)
|
|
459
|
+
assert result.returncode == 0, f"stderr: {result.stderr}"
|
|
460
|
+
assert "cached plan must not change result type" not in result.stderr
|
|
461
|
+
# The final export reflects the recreated (TEXT) view.
|
|
462
|
+
assert "alpha" in out.read_text()
|
|
463
|
+
|
|
464
|
+
_exec_pg("DROP VIEW IF EXISTS val_summ")
|
|
465
|
+
_exec_pg("DROP TABLE IF EXISTS val_src")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{execsql2-2.21.1 → execsql2-2.21.2}/extras/plugin-template/src/execsql_plugin_YOURNAME/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|