execsql2 2.16.5__tar.gz → 2.16.7__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.
Files changed (319) hide show
  1. {execsql2-2.16.5 → execsql2-2.16.7}/CHANGELOG.md +18 -0
  2. {execsql2-2.16.5 → execsql2-2.16.7}/PKG-INFO +1 -1
  3. {execsql2-2.16.5 → execsql2-2.16.7}/pyproject.toml +2 -2
  4. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/format.py +16 -2
  5. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/script/executor.py +15 -1
  6. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_executor.py +35 -0
  7. {execsql2-2.16.5 → execsql2-2.16.7}/uv.lock +1 -1
  8. {execsql2-2.16.5 → execsql2-2.16.7}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  9. {execsql2-2.16.5 → execsql2-2.16.7}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  10. {execsql2-2.16.5 → execsql2-2.16.7}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  11. {execsql2-2.16.5 → execsql2-2.16.7}/.github/workflows/ci-cd.yml +0 -0
  12. {execsql2-2.16.5 → execsql2-2.16.7}/.gitignore +0 -0
  13. {execsql2-2.16.5 → execsql2-2.16.7}/.pre-commit-config.yaml +0 -0
  14. {execsql2-2.16.5 → execsql2-2.16.7}/.pre-commit-hooks.yaml +0 -0
  15. {execsql2-2.16.5 → execsql2-2.16.7}/.python-version +0 -0
  16. {execsql2-2.16.5 → execsql2-2.16.7}/.readthedocs.yaml +0 -0
  17. {execsql2-2.16.5 → execsql2-2.16.7}/CONTRIBUTING.md +0 -0
  18. {execsql2-2.16.5 → execsql2-2.16.7}/LICENSE.txt +0 -0
  19. {execsql2-2.16.5 → execsql2-2.16.7}/NOTICE +0 -0
  20. {execsql2-2.16.5 → execsql2-2.16.7}/README.md +0 -0
  21. {execsql2-2.16.5 → execsql2-2.16.7}/SECURITY.md +0 -0
  22. {execsql2-2.16.5 → execsql2-2.16.7}/docs/about/contributors.md +0 -0
  23. {execsql2-2.16.5 → execsql2-2.16.7}/docs/about/copyright.md +0 -0
  24. {execsql2-2.16.5 → execsql2-2.16.7}/docs/about/divergence.md +0 -0
  25. {execsql2-2.16.5 → execsql2-2.16.7}/docs/api/cli.md +0 -0
  26. {execsql2-2.16.5 → execsql2-2.16.7}/docs/api/db.md +0 -0
  27. {execsql2-2.16.5 → execsql2-2.16.7}/docs/api/exporters.md +0 -0
  28. {execsql2-2.16.5 → execsql2-2.16.7}/docs/api/importers.md +0 -0
  29. {execsql2-2.16.5 → execsql2-2.16.7}/docs/api/index.md +0 -0
  30. {execsql2-2.16.5 → execsql2-2.16.7}/docs/api/metacommands.md +0 -0
  31. {execsql2-2.16.5 → execsql2-2.16.7}/docs/dev/adding_db_adapters.md +0 -0
  32. {execsql2-2.16.5 → execsql2-2.16.7}/docs/dev/adding_exporters.md +0 -0
  33. {execsql2-2.16.5 → execsql2-2.16.7}/docs/dev/adding_importers.md +0 -0
  34. {execsql2-2.16.5 → execsql2-2.16.7}/docs/dev/adding_metacommands.md +0 -0
  35. {execsql2-2.16.5 → execsql2-2.16.7}/docs/dev/architecture.md +0 -0
  36. {execsql2-2.16.5 → execsql2-2.16.7}/docs/getting-started/installation.md +0 -0
  37. {execsql2-2.16.5 → execsql2-2.16.7}/docs/getting-started/requirements.md +0 -0
  38. {execsql2-2.16.5 → execsql2-2.16.7}/docs/getting-started/syntax.md +0 -0
  39. {execsql2-2.16.5 → execsql2-2.16.7}/docs/guides/debugging.md +0 -0
  40. {execsql2-2.16.5 → execsql2-2.16.7}/docs/guides/documentation.md +0 -0
  41. {execsql2-2.16.5 → execsql2-2.16.7}/docs/guides/encoding.md +0 -0
  42. {execsql2-2.16.5 → execsql2-2.16.7}/docs/guides/examples.md +0 -0
  43. {execsql2-2.16.5 → execsql2-2.16.7}/docs/guides/formatter.md +0 -0
  44. {execsql2-2.16.5 → execsql2-2.16.7}/docs/guides/logging.md +0 -0
  45. {execsql2-2.16.5 → execsql2-2.16.7}/docs/guides/sql_syntax.md +0 -0
  46. {execsql2-2.16.5 → execsql2-2.16.7}/docs/guides/usage.md +0 -0
  47. {execsql2-2.16.5 → execsql2-2.16.7}/docs/guides/using_scripts.md +0 -0
  48. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/Compare_planets.png +0 -0
  49. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/actions.png +0 -0
  50. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/actions2.png +0 -0
  51. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/checkboxes.png +0 -0
  52. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/connect.b64 +0 -0
  53. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/connect.png +0 -0
  54. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/create_conf.png +0 -0
  55. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/data_error1_screenshot.jpg +0 -0
  56. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/entry_form.png +0 -0
  57. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/execsql_console.png +0 -0
  58. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/execsql_logo_01.png +0 -0
  59. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/fatals.png +0 -0
  60. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/logo_small.png +0 -0
  61. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/pause_terminal.png +0 -0
  62. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/pause_terminal_sm.b64 +0 -0
  63. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/pause_terminal_sm.png +0 -0
  64. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/prompt_compare.png +0 -0
  65. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/set_build_commands.jpg +0 -0
  66. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/unit_conversions.b64 +0 -0
  67. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/unit_conversions_029.png +0 -0
  68. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/unmatched.png +0 -0
  69. {execsql2-2.16.5 → execsql2-2.16.7}/docs/images/vim_execsql_highlight.png +0 -0
  70. {execsql2-2.16.5 → execsql2-2.16.7}/docs/index.md +0 -0
  71. {execsql2-2.16.5 → execsql2-2.16.7}/docs/reference/configuration.md +0 -0
  72. {execsql2-2.16.5 → execsql2-2.16.7}/docs/reference/metacommands.md +0 -0
  73. {execsql2-2.16.5 → execsql2-2.16.7}/docs/reference/security.md +0 -0
  74. {execsql2-2.16.5 → execsql2-2.16.7}/docs/reference/substitution_vars.md +0 -0
  75. {execsql2-2.16.5 → execsql2-2.16.7}/extras/plugin-template/README.md +0 -0
  76. {execsql2-2.16.5 → execsql2-2.16.7}/extras/plugin-template/pyproject.toml +0 -0
  77. {execsql2-2.16.5 → execsql2-2.16.7}/extras/plugin-template/src/execsql_plugin_YOURNAME/__init__.py +0 -0
  78. {execsql2-2.16.5 → execsql2-2.16.7}/extras/plugin-template/tests/test_plugin.py.example +0 -0
  79. {execsql2-2.16.5 → execsql2-2.16.7}/extras/vscode-execsql/README.md +0 -0
  80. {execsql2-2.16.5 → execsql2-2.16.7}/extras/vscode-execsql/package.json +0 -0
  81. {execsql2-2.16.5 → execsql2-2.16.7}/extras/vscode-execsql/syntaxes/execsql.tmLanguage.json +0 -0
  82. {execsql2-2.16.5 → execsql2-2.16.7}/justfile +0 -0
  83. {execsql2-2.16.5 → execsql2-2.16.7}/scripts/generate_vscode_grammar.py +0 -0
  84. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/__init__.py +0 -0
  85. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/__main__.py +0 -0
  86. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/api.py +0 -0
  87. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/cli/__init__.py +0 -0
  88. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/cli/dsn.py +0 -0
  89. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/cli/help.py +0 -0
  90. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/cli/lint.py +0 -0
  91. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/cli/lint_ast.py +0 -0
  92. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/cli/run.py +0 -0
  93. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/config.py +0 -0
  94. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/__init__.py +0 -0
  95. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/access.py +0 -0
  96. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/base.py +0 -0
  97. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/dsn.py +0 -0
  98. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/duckdb.py +0 -0
  99. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/factory.py +0 -0
  100. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/firebird.py +0 -0
  101. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/mysql.py +0 -0
  102. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/oracle.py +0 -0
  103. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/postgres.py +0 -0
  104. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/sqlite.py +0 -0
  105. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/db/sqlserver.py +0 -0
  106. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/debug/__init__.py +0 -0
  107. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/debug/repl.py +0 -0
  108. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exceptions.py +0 -0
  109. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/__init__.py +0 -0
  110. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/base.py +0 -0
  111. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/delimited.py +0 -0
  112. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/duckdb.py +0 -0
  113. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/feather.py +0 -0
  114. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/html.py +0 -0
  115. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/json.py +0 -0
  116. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/latex.py +0 -0
  117. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/markdown.py +0 -0
  118. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/ods.py +0 -0
  119. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/parquet.py +0 -0
  120. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/pretty.py +0 -0
  121. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/protocol.py +0 -0
  122. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/raw.py +0 -0
  123. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/sqlite.py +0 -0
  124. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/templates.py +0 -0
  125. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/values.py +0 -0
  126. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/xls.py +0 -0
  127. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/xlsx.py +0 -0
  128. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/xml.py +0 -0
  129. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/yaml.py +0 -0
  130. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/exporters/zip.py +0 -0
  131. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/gui/__init__.py +0 -0
  132. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/gui/base.py +0 -0
  133. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/gui/console.py +0 -0
  134. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/gui/desktop.py +0 -0
  135. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/gui/tui.py +0 -0
  136. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/importers/__init__.py +0 -0
  137. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/importers/base.py +0 -0
  138. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/importers/csv.py +0 -0
  139. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/importers/feather.py +0 -0
  140. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/importers/json.py +0 -0
  141. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/importers/ods.py +0 -0
  142. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/importers/xls.py +0 -0
  143. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/__init__.py +0 -0
  144. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/conditions.py +0 -0
  145. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/connect.py +0 -0
  146. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/control.py +0 -0
  147. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/data.py +0 -0
  148. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/debug.py +0 -0
  149. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/dispatch.py +0 -0
  150. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/io.py +0 -0
  151. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/io_export.py +0 -0
  152. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/io_fileops.py +0 -0
  153. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/io_import.py +0 -0
  154. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/io_write.py +0 -0
  155. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/prompt.py +0 -0
  156. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/script_ext.py +0 -0
  157. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/system.py +0 -0
  158. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/metacommands/upsert.py +0 -0
  159. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/models.py +0 -0
  160. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/parser.py +0 -0
  161. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/plugins.py +0 -0
  162. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/py.typed +0 -0
  163. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/script/__init__.py +0 -0
  164. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/script/ast.py +0 -0
  165. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/script/control.py +0 -0
  166. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/script/engine.py +0 -0
  167. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/script/parser.py +0 -0
  168. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/script/variables.py +0 -0
  169. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/state.py +0 -0
  170. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/types.py +0 -0
  171. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/__init__.py +0 -0
  172. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/auth.py +0 -0
  173. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/crypto.py +0 -0
  174. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/datetime.py +0 -0
  175. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/errors.py +0 -0
  176. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/fileio.py +0 -0
  177. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/gui.py +0 -0
  178. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/mail.py +0 -0
  179. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/numeric.py +0 -0
  180. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/regex.py +0 -0
  181. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/strings.py +0 -0
  182. {execsql2-2.16.5 → execsql2-2.16.7}/src/execsql/utils/timer.py +0 -0
  183. {execsql2-2.16.5 → execsql2-2.16.7}/templates/README.md +0 -0
  184. {execsql2-2.16.5 → execsql2-2.16.7}/templates/config_settings.sqlite +0 -0
  185. {execsql2-2.16.5 → execsql2-2.16.7}/templates/example_config_prompt.sql +0 -0
  186. {execsql2-2.16.5 → execsql2-2.16.7}/templates/execsql.conf +0 -0
  187. {execsql2-2.16.5 → execsql2-2.16.7}/templates/make_config_db.sql +0 -0
  188. {execsql2-2.16.5 → execsql2-2.16.7}/templates/md_compare.sql +0 -0
  189. {execsql2-2.16.5 → execsql2-2.16.7}/templates/md_glossary.sql +0 -0
  190. {execsql2-2.16.5 → execsql2-2.16.7}/templates/md_upsert.sql +0 -0
  191. {execsql2-2.16.5 → execsql2-2.16.7}/templates/pg_compare.sql +0 -0
  192. {execsql2-2.16.5 → execsql2-2.16.7}/templates/pg_glossary.sql +0 -0
  193. {execsql2-2.16.5 → execsql2-2.16.7}/templates/pg_upsert.sql +0 -0
  194. {execsql2-2.16.5 → execsql2-2.16.7}/templates/script_template.sql +0 -0
  195. {execsql2-2.16.5 → execsql2-2.16.7}/templates/ss_compare.sql +0 -0
  196. {execsql2-2.16.5 → execsql2-2.16.7}/templates/ss_glossary.sql +0 -0
  197. {execsql2-2.16.5 → execsql2-2.16.7}/templates/ss_upsert.sql +0 -0
  198. {execsql2-2.16.5 → execsql2-2.16.7}/tests/__init__.py +0 -0
  199. {execsql2-2.16.5 → execsql2-2.16.7}/tests/cli/__init__.py +0 -0
  200. {execsql2-2.16.5 → execsql2-2.16.7}/tests/cli/test_cli.py +0 -0
  201. {execsql2-2.16.5 → execsql2-2.16.7}/tests/cli/test_cli_e2e.py +0 -0
  202. {execsql2-2.16.5 → execsql2-2.16.7}/tests/cli/test_cli_run.py +0 -0
  203. {execsql2-2.16.5 → execsql2-2.16.7}/tests/cli/test_lint.py +0 -0
  204. {execsql2-2.16.5 → execsql2-2.16.7}/tests/cli/test_ping.py +0 -0
  205. {execsql2-2.16.5 → execsql2-2.16.7}/tests/cli/test_profile.py +0 -0
  206. {execsql2-2.16.5 → execsql2-2.16.7}/tests/conftest.py +0 -0
  207. {execsql2-2.16.5 → execsql2-2.16.7}/tests/db/__init__.py +0 -0
  208. {execsql2-2.16.5 → execsql2-2.16.7}/tests/db/test_base.py +0 -0
  209. {execsql2-2.16.5 → execsql2-2.16.7}/tests/db/test_db_adapters_mocked.py +0 -0
  210. {execsql2-2.16.5 → execsql2-2.16.7}/tests/db/test_dsn.py +0 -0
  211. {execsql2-2.16.5 → execsql2-2.16.7}/tests/db/test_duckdb.py +0 -0
  212. {execsql2-2.16.5 → execsql2-2.16.7}/tests/db/test_factory.py +0 -0
  213. {execsql2-2.16.5 → execsql2-2.16.7}/tests/db/test_postgres.py +0 -0
  214. {execsql2-2.16.5 → execsql2-2.16.7}/tests/db/test_sqlite.py +0 -0
  215. {execsql2-2.16.5 → execsql2-2.16.7}/tests/db/test_sqlite_extra.py +0 -0
  216. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/__init__.py +0 -0
  217. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_base.py +0 -0
  218. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_db.py +0 -0
  219. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_delimited.py +0 -0
  220. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_duckdb_exporter.py +0 -0
  221. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_exporters.py +0 -0
  222. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_feather.py +0 -0
  223. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_html_extended.py +0 -0
  224. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_html_latex.py +0 -0
  225. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_json.py +0 -0
  226. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_json_extended.py +0 -0
  227. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_latex_extended.py +0 -0
  228. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_markdown.py +0 -0
  229. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_ods.py +0 -0
  230. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_parquet.py +0 -0
  231. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_pretty_extended.py +0 -0
  232. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_raw_extended.py +0 -0
  233. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_sqlite_exporter.py +0 -0
  234. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_templates.py +0 -0
  235. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_templates_extended.py +0 -0
  236. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_values_extended.py +0 -0
  237. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_xls_xlsx.py +0 -0
  238. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_xlsx.py +0 -0
  239. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_xml.py +0 -0
  240. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_yaml.py +0 -0
  241. {execsql2-2.16.5 → execsql2-2.16.7}/tests/exporters/test_zip.py +0 -0
  242. {execsql2-2.16.5 → execsql2-2.16.7}/tests/gui/__init__.py +0 -0
  243. {execsql2-2.16.5 → execsql2-2.16.7}/tests/gui/test_backends.py +0 -0
  244. {execsql2-2.16.5 → execsql2-2.16.7}/tests/gui/test_compare_stats.py +0 -0
  245. {execsql2-2.16.5 → execsql2-2.16.7}/tests/gui/test_compute_row_diffs.py +0 -0
  246. {execsql2-2.16.5 → execsql2-2.16.7}/tests/importers/__init__.py +0 -0
  247. {execsql2-2.16.5 → execsql2-2.16.7}/tests/importers/test_base_extended.py +0 -0
  248. {execsql2-2.16.5 → execsql2-2.16.7}/tests/importers/test_csv_edge_cases.py +0 -0
  249. {execsql2-2.16.5 → execsql2-2.16.7}/tests/importers/test_csv_importer.py +0 -0
  250. {execsql2-2.16.5 → execsql2-2.16.7}/tests/importers/test_feather_importer.py +0 -0
  251. {execsql2-2.16.5 → execsql2-2.16.7}/tests/importers/test_json_importer.py +0 -0
  252. {execsql2-2.16.5 → execsql2-2.16.7}/tests/importers/test_ods_importer.py +0 -0
  253. {execsql2-2.16.5 → execsql2-2.16.7}/tests/importers/test_xls_importer.py +0 -0
  254. {execsql2-2.16.5 → execsql2-2.16.7}/tests/integration/__init__.py +0 -0
  255. {execsql2-2.16.5 → execsql2-2.16.7}/tests/integration/conftest.py +0 -0
  256. {execsql2-2.16.5 → execsql2-2.16.7}/tests/integration/test_dsn.py +0 -0
  257. {execsql2-2.16.5 → execsql2-2.16.7}/tests/integration/test_duckdb.py +0 -0
  258. {execsql2-2.16.5 → execsql2-2.16.7}/tests/integration/test_mysql.py +0 -0
  259. {execsql2-2.16.5 → execsql2-2.16.7}/tests/integration/test_postgres.py +0 -0
  260. {execsql2-2.16.5 → execsql2-2.16.7}/tests/integration/test_sqlite.py +0 -0
  261. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/__init__.py +0 -0
  262. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_assert.py +0 -0
  263. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_breakpoint.py +0 -0
  264. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_connect.py +0 -0
  265. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_io_export.py +0 -0
  266. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_io_import.py +0 -0
  267. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_metacommands.py +0 -0
  268. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_metacommands_connect.py +0 -0
  269. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_metacommands_data.py +0 -0
  270. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_metacommands_extended.py +0 -0
  271. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_metacommands_fileops_extra.py +0 -0
  272. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_metacommands_io.py +0 -0
  273. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_metacommands_io_write_extra.py +0 -0
  274. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_metacommands_script_ext.py +0 -0
  275. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_metacommands_system.py +0 -0
  276. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_metacommands_system_extra.py +0 -0
  277. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_pg_upsert.py +0 -0
  278. {execsql2-2.16.5 → execsql2-2.16.7}/tests/metacommands/test_row_count.py +0 -0
  279. {execsql2-2.16.5 → execsql2-2.16.7}/tests/scripts/__init__.py +0 -0
  280. {execsql2-2.16.5 → execsql2-2.16.7}/tests/scripts/fixtures/control_flow.sql +0 -0
  281. {execsql2-2.16.5 → execsql2-2.16.7}/tests/scripts/fixtures/io_roundtrip.sql +0 -0
  282. {execsql2-2.16.5 → execsql2-2.16.7}/tests/scripts/fixtures/parse_only/parse_tree.sql +0 -0
  283. {execsql2-2.16.5 → execsql2-2.16.7}/tests/scripts/fixtures/smoke.sql +0 -0
  284. {execsql2-2.16.5 → execsql2-2.16.7}/tests/scripts/test_sql_scripts.py +0 -0
  285. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_api.py +0 -0
  286. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_ast.py +0 -0
  287. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_ast_parser.py +0 -0
  288. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_config.py +0 -0
  289. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_config_data.py +0 -0
  290. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_config_extended.py +0 -0
  291. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_debug_repl.py +0 -0
  292. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_engine.py +0 -0
  293. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_error_messages.py +0 -0
  294. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_exceptions.py +0 -0
  295. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_format.py +0 -0
  296. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_mail.py +0 -0
  297. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_models.py +0 -0
  298. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_package.py +0 -0
  299. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_parser.py +0 -0
  300. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_plugins.py +0 -0
  301. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_registry.py +0 -0
  302. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_script.py +0 -0
  303. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_state.py +0 -0
  304. {execsql2-2.16.5 → execsql2-2.16.7}/tests/test_types.py +0 -0
  305. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/__init__.py +0 -0
  306. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_auth.py +0 -0
  307. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_auth_extra.py +0 -0
  308. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_crypto.py +0 -0
  309. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_datetime.py +0 -0
  310. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_errors.py +0 -0
  311. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_errors_extra.py +0 -0
  312. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_fileio.py +0 -0
  313. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_fileio_extra.py +0 -0
  314. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_numeric.py +0 -0
  315. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_regex.py +0 -0
  316. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_strings.py +0 -0
  317. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_timer.py +0 -0
  318. {execsql2-2.16.5 → execsql2-2.16.7}/tests/utils/test_timer_extra.py +0 -0
  319. {execsql2-2.16.5 → execsql2-2.16.7}/zensical.toml +0 -0
@@ -13,6 +13,24 @@ ______________________________________________________________________
13
13
 
14
14
  ______________________________________________________________________
15
15
 
16
+ ## [2.16.7] - 2026-04-30
17
+
18
+ ### Fixed
19
+
20
+ - ANDIF/ORIF conditions now short-circuit: `IF (sub_defined(x)) ANDIF (not sub_empty(x))` no longer evaluates `sub_empty` when `sub_defined` returns false. Previously all modifiers were evaluated unconditionally, causing `sub_empty` to throw "Unrecognized substitution variable" on undefined variables.
21
+ - Error reports for IF, LOOP, and INCLUDE nodes now show the correct source line and metacommand text instead of the previous command's location.
22
+
23
+ ______________________________________________________________________
24
+
25
+ ## [2.16.6] - 2026-04-30
26
+
27
+ ### Fixed
28
+
29
+ - `execsql-format` no longer corrupts PL/pgSQL function bodies inside `$$`-delimited blocks. sqlglot does not understand PL/pgSQL and was rewriting `IF NOT EXISTS ... END IF`, `IF ... THEN RETURN ... END IF`, and similar constructs as `COMMIT;`. The formatter now tracks `$$` boundaries and skips sqlglot formatting for any SQL block containing dollar-quoted content.
30
+ - Debug REPL `.vars` now shows `~` local and `#` param variables from the current stack frame, not just global variables. `.vars ~myvar` and `.set ~myvar value` also correctly read/write the stack frame's local scope instead of the global pool.
31
+
32
+ ______________________________________________________________________
33
+
16
34
  ## [2.16.5] - 2026-04-30
17
35
 
18
36
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: execsql2
3
- Version: 2.16.5
3
+ Version: 2.16.7
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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "execsql2"
7
- version = "2.16.5"
7
+ version = "2.16.7"
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" }
@@ -165,7 +165,7 @@ skip-magic-trailing-comma = false
165
165
  line-ending = "auto"
166
166
 
167
167
  [tool.bumpversion]
168
- current_version = "2.16.5"
168
+ current_version = "2.16.7"
169
169
  commit = true
170
170
  tag = true
171
171
  tag_name = "v{new_version}"
@@ -242,16 +242,27 @@ def format_file(source: str, indent: int = 4, use_sql: bool = True) -> str:
242
242
  sql_acc: list[str] = []
243
243
  output: list[str] = []
244
244
 
245
+ in_dollar_quote = False
246
+
245
247
  def flush_sql() -> None:
248
+ nonlocal in_dollar_quote
246
249
  if sql_acc:
247
- output.extend(format_sql_block(sql_acc, depth, indent, use_sql))
250
+ # If any line in the accumulated block is inside a $$-delimited
251
+ # region, skip sqlglot formatting entirely. PL/pgSQL function
252
+ # bodies contain IF/END IF, LOOP, RETURN, etc. that sqlglot does
253
+ # not understand and will corrupt (e.g., rewriting to COMMIT).
254
+ safe_for_sqlglot = use_sql and not in_dollar_quote
255
+ output.extend(format_sql_block(sql_acc, depth, indent, safe_for_sqlglot))
248
256
  sql_acc.clear()
249
257
 
250
258
  for raw_line in source.expandtabs(4).splitlines():
251
259
  m = METACOMMAND_RE.match(raw_line)
252
260
 
253
261
  if not raw_line.strip():
254
- flush_sql()
262
+ if not in_dollar_quote:
263
+ flush_sql()
264
+ else:
265
+ sql_acc.append(raw_line)
255
266
  output.append("")
256
267
 
257
268
  elif m:
@@ -279,6 +290,9 @@ def format_file(source: str, indent: int = 4, use_sql: bool = True) -> str:
279
290
  output.append(format_metacommand(payload, depth, indent))
280
291
 
281
292
  else:
293
+ # Track $$ boundaries to prevent sqlglot from mangling PL/pgSQL
294
+ if "$$" in raw_line and raw_line.count("$$") % 2 == 1:
295
+ in_dollar_quote = not in_dollar_quote
282
296
  sql_acc.append(raw_line)
283
297
 
284
298
  flush_sql()
@@ -139,13 +139,24 @@ def _eval_condition(
139
139
  condition: str,
140
140
  modifiers: list[ConditionModifier] | None = None,
141
141
  ) -> bool:
142
- """Evaluate a condition string with optional ANDIF/ORIF modifiers."""
142
+ """Evaluate a condition string with optional ANDIF/ORIF modifiers.
143
+
144
+ Short-circuits ANDIF (stops on first False) and ORIF (stops on first True)
145
+ so that patterns like ``IF (sub_defined(x)) ANDIF (not sub_empty(x))``
146
+ don't evaluate ``sub_empty`` when ``x`` is undefined.
147
+ """
143
148
  effective_locals = _stack_localvars(ctx)
144
149
  expanded = substitute_vars(condition, effective_locals, ctx=ctx)
145
150
  result = xcmd_test(expanded)
146
151
 
147
152
  if modifiers:
148
153
  for mod in modifiers:
154
+ # Short-circuit: AND with False can't become True,
155
+ # OR with True can't become False.
156
+ if mod.kind == "AND" and not result:
157
+ continue
158
+ if mod.kind == "OR" and result:
159
+ continue
149
160
  mod_expanded = substitute_vars(mod.condition, effective_locals, ctx=ctx)
150
161
  mod_result = xcmd_test(mod_expanded)
151
162
  if mod.kind == "AND":
@@ -353,9 +364,11 @@ def _execute_node(
353
364
  _exec_metacommand(ctx, command, node.span.file, node.span.start_line, localvars)
354
365
 
355
366
  elif isinstance(node, IfBlock):
367
+ ctx.last_command = _FakeScriptCmd(node)
356
368
  _execute_if(ctx, node, localvars, in_loop=in_loop)
357
369
 
358
370
  elif isinstance(node, LoopBlock):
371
+ ctx.last_command = _FakeScriptCmd(node)
359
372
  _execute_loop(ctx, node, localvars)
360
373
 
361
374
  elif isinstance(node, BatchBlock):
@@ -368,6 +381,7 @@ def _execute_node(
368
381
  _execute_sql_block(ctx, node, localvars, in_loop=in_loop)
369
382
 
370
383
  elif isinstance(node, IncludeDirective):
384
+ ctx.last_command = _FakeScriptCmd(node)
371
385
  _execute_include(ctx, node, localvars)
372
386
 
373
387
 
@@ -434,6 +434,41 @@ class TestAssert:
434
434
  assert result.returncode != 0
435
435
 
436
436
 
437
+ # ---------------------------------------------------------------------------
438
+ # Short-circuit ANDIF/ORIF
439
+ # ---------------------------------------------------------------------------
440
+
441
+
442
+ class TestShortCircuit:
443
+ def test_andif_short_circuits(self, tmp_path):
444
+ """ANDIF does not evaluate sub_empty when sub_defined is false."""
445
+ script = (
446
+ "CREATE TABLE t (x INT);\n"
447
+ "-- !x! IF (sub_defined(undefined_var))\n"
448
+ "-- !x! ANDIF (not sub_empty(undefined_var))\n"
449
+ "INSERT INTO t VALUES (1);\n"
450
+ "-- !x! ELSE\n"
451
+ "INSERT INTO t VALUES (2);\n"
452
+ "-- !x! ENDIF\n"
453
+ )
454
+ result = _run_ast(script, tmp_path)
455
+ assert result.returncode == 0, result.stderr
456
+ assert _query_db(tmp_path, "SELECT x FROM t") == [(2,)]
457
+
458
+ def test_orif_short_circuits(self, tmp_path):
459
+ """ORIF does not evaluate when first condition is already true."""
460
+ script = (
461
+ "CREATE TABLE t (x INT);\n"
462
+ "-- !x! IF (TRUE)\n"
463
+ "-- !x! ORIF (not sub_empty(undefined_var))\n"
464
+ "INSERT INTO t VALUES (1);\n"
465
+ "-- !x! ENDIF\n"
466
+ )
467
+ result = _run_ast(script, tmp_path)
468
+ assert result.returncode == 0, result.stderr
469
+ assert _query_db(tmp_path, "SELECT x FROM t") == [(1,)]
470
+
471
+
437
472
  # ---------------------------------------------------------------------------
438
473
  # Profiling
439
474
  # ---------------------------------------------------------------------------
@@ -648,7 +648,7 @@ wheels = [
648
648
 
649
649
  [[package]]
650
650
  name = "execsql2"
651
- version = "2.16.5"
651
+ version = "2.16.7"
652
652
  source = { editable = "." }
653
653
  dependencies = [
654
654
  { name = "python-dateutil" },
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