execsql2 2.16.3__tar.gz → 2.16.4__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.3 → execsql2-2.16.4}/CHANGELOG.md +8 -0
  2. {execsql2-2.16.3 → execsql2-2.16.4}/PKG-INFO +1 -1
  3. {execsql2-2.16.3 → execsql2-2.16.4}/docs/about/divergence.md +1 -0
  4. {execsql2-2.16.3 → execsql2-2.16.4}/pyproject.toml +2 -2
  5. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/script/executor.py +34 -0
  6. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_executor.py +26 -0
  7. {execsql2-2.16.3 → execsql2-2.16.4}/uv.lock +1 -1
  8. {execsql2-2.16.3 → execsql2-2.16.4}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  9. {execsql2-2.16.3 → execsql2-2.16.4}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  10. {execsql2-2.16.3 → execsql2-2.16.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  11. {execsql2-2.16.3 → execsql2-2.16.4}/.github/workflows/ci-cd.yml +0 -0
  12. {execsql2-2.16.3 → execsql2-2.16.4}/.gitignore +0 -0
  13. {execsql2-2.16.3 → execsql2-2.16.4}/.pre-commit-config.yaml +0 -0
  14. {execsql2-2.16.3 → execsql2-2.16.4}/.pre-commit-hooks.yaml +0 -0
  15. {execsql2-2.16.3 → execsql2-2.16.4}/.python-version +0 -0
  16. {execsql2-2.16.3 → execsql2-2.16.4}/.readthedocs.yaml +0 -0
  17. {execsql2-2.16.3 → execsql2-2.16.4}/CONTRIBUTING.md +0 -0
  18. {execsql2-2.16.3 → execsql2-2.16.4}/LICENSE.txt +0 -0
  19. {execsql2-2.16.3 → execsql2-2.16.4}/NOTICE +0 -0
  20. {execsql2-2.16.3 → execsql2-2.16.4}/README.md +0 -0
  21. {execsql2-2.16.3 → execsql2-2.16.4}/SECURITY.md +0 -0
  22. {execsql2-2.16.3 → execsql2-2.16.4}/docs/about/contributors.md +0 -0
  23. {execsql2-2.16.3 → execsql2-2.16.4}/docs/about/copyright.md +0 -0
  24. {execsql2-2.16.3 → execsql2-2.16.4}/docs/api/cli.md +0 -0
  25. {execsql2-2.16.3 → execsql2-2.16.4}/docs/api/db.md +0 -0
  26. {execsql2-2.16.3 → execsql2-2.16.4}/docs/api/exporters.md +0 -0
  27. {execsql2-2.16.3 → execsql2-2.16.4}/docs/api/importers.md +0 -0
  28. {execsql2-2.16.3 → execsql2-2.16.4}/docs/api/index.md +0 -0
  29. {execsql2-2.16.3 → execsql2-2.16.4}/docs/api/metacommands.md +0 -0
  30. {execsql2-2.16.3 → execsql2-2.16.4}/docs/dev/adding_db_adapters.md +0 -0
  31. {execsql2-2.16.3 → execsql2-2.16.4}/docs/dev/adding_exporters.md +0 -0
  32. {execsql2-2.16.3 → execsql2-2.16.4}/docs/dev/adding_importers.md +0 -0
  33. {execsql2-2.16.3 → execsql2-2.16.4}/docs/dev/adding_metacommands.md +0 -0
  34. {execsql2-2.16.3 → execsql2-2.16.4}/docs/dev/architecture.md +0 -0
  35. {execsql2-2.16.3 → execsql2-2.16.4}/docs/getting-started/installation.md +0 -0
  36. {execsql2-2.16.3 → execsql2-2.16.4}/docs/getting-started/requirements.md +0 -0
  37. {execsql2-2.16.3 → execsql2-2.16.4}/docs/getting-started/syntax.md +0 -0
  38. {execsql2-2.16.3 → execsql2-2.16.4}/docs/guides/debugging.md +0 -0
  39. {execsql2-2.16.3 → execsql2-2.16.4}/docs/guides/documentation.md +0 -0
  40. {execsql2-2.16.3 → execsql2-2.16.4}/docs/guides/encoding.md +0 -0
  41. {execsql2-2.16.3 → execsql2-2.16.4}/docs/guides/examples.md +0 -0
  42. {execsql2-2.16.3 → execsql2-2.16.4}/docs/guides/formatter.md +0 -0
  43. {execsql2-2.16.3 → execsql2-2.16.4}/docs/guides/logging.md +0 -0
  44. {execsql2-2.16.3 → execsql2-2.16.4}/docs/guides/sql_syntax.md +0 -0
  45. {execsql2-2.16.3 → execsql2-2.16.4}/docs/guides/usage.md +0 -0
  46. {execsql2-2.16.3 → execsql2-2.16.4}/docs/guides/using_scripts.md +0 -0
  47. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/Compare_planets.png +0 -0
  48. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/actions.png +0 -0
  49. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/actions2.png +0 -0
  50. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/checkboxes.png +0 -0
  51. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/connect.b64 +0 -0
  52. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/connect.png +0 -0
  53. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/create_conf.png +0 -0
  54. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/data_error1_screenshot.jpg +0 -0
  55. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/entry_form.png +0 -0
  56. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/execsql_console.png +0 -0
  57. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/execsql_logo_01.png +0 -0
  58. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/fatals.png +0 -0
  59. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/logo_small.png +0 -0
  60. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/pause_terminal.png +0 -0
  61. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/pause_terminal_sm.b64 +0 -0
  62. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/pause_terminal_sm.png +0 -0
  63. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/prompt_compare.png +0 -0
  64. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/set_build_commands.jpg +0 -0
  65. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/unit_conversions.b64 +0 -0
  66. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/unit_conversions_029.png +0 -0
  67. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/unmatched.png +0 -0
  68. {execsql2-2.16.3 → execsql2-2.16.4}/docs/images/vim_execsql_highlight.png +0 -0
  69. {execsql2-2.16.3 → execsql2-2.16.4}/docs/index.md +0 -0
  70. {execsql2-2.16.3 → execsql2-2.16.4}/docs/reference/configuration.md +0 -0
  71. {execsql2-2.16.3 → execsql2-2.16.4}/docs/reference/metacommands.md +0 -0
  72. {execsql2-2.16.3 → execsql2-2.16.4}/docs/reference/security.md +0 -0
  73. {execsql2-2.16.3 → execsql2-2.16.4}/docs/reference/substitution_vars.md +0 -0
  74. {execsql2-2.16.3 → execsql2-2.16.4}/extras/plugin-template/README.md +0 -0
  75. {execsql2-2.16.3 → execsql2-2.16.4}/extras/plugin-template/pyproject.toml +0 -0
  76. {execsql2-2.16.3 → execsql2-2.16.4}/extras/plugin-template/src/execsql_plugin_YOURNAME/__init__.py +0 -0
  77. {execsql2-2.16.3 → execsql2-2.16.4}/extras/plugin-template/tests/test_plugin.py.example +0 -0
  78. {execsql2-2.16.3 → execsql2-2.16.4}/extras/vscode-execsql/README.md +0 -0
  79. {execsql2-2.16.3 → execsql2-2.16.4}/extras/vscode-execsql/package.json +0 -0
  80. {execsql2-2.16.3 → execsql2-2.16.4}/extras/vscode-execsql/syntaxes/execsql.tmLanguage.json +0 -0
  81. {execsql2-2.16.3 → execsql2-2.16.4}/justfile +0 -0
  82. {execsql2-2.16.3 → execsql2-2.16.4}/scripts/generate_vscode_grammar.py +0 -0
  83. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/__init__.py +0 -0
  84. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/__main__.py +0 -0
  85. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/api.py +0 -0
  86. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/cli/__init__.py +0 -0
  87. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/cli/dsn.py +0 -0
  88. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/cli/help.py +0 -0
  89. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/cli/lint.py +0 -0
  90. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/cli/lint_ast.py +0 -0
  91. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/cli/run.py +0 -0
  92. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/config.py +0 -0
  93. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/__init__.py +0 -0
  94. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/access.py +0 -0
  95. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/base.py +0 -0
  96. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/dsn.py +0 -0
  97. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/duckdb.py +0 -0
  98. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/factory.py +0 -0
  99. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/firebird.py +0 -0
  100. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/mysql.py +0 -0
  101. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/oracle.py +0 -0
  102. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/postgres.py +0 -0
  103. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/sqlite.py +0 -0
  104. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/db/sqlserver.py +0 -0
  105. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/debug/__init__.py +0 -0
  106. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/debug/repl.py +0 -0
  107. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exceptions.py +0 -0
  108. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/__init__.py +0 -0
  109. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/base.py +0 -0
  110. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/delimited.py +0 -0
  111. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/duckdb.py +0 -0
  112. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/feather.py +0 -0
  113. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/html.py +0 -0
  114. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/json.py +0 -0
  115. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/latex.py +0 -0
  116. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/markdown.py +0 -0
  117. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/ods.py +0 -0
  118. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/parquet.py +0 -0
  119. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/pretty.py +0 -0
  120. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/protocol.py +0 -0
  121. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/raw.py +0 -0
  122. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/sqlite.py +0 -0
  123. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/templates.py +0 -0
  124. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/values.py +0 -0
  125. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/xls.py +0 -0
  126. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/xlsx.py +0 -0
  127. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/xml.py +0 -0
  128. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/yaml.py +0 -0
  129. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/exporters/zip.py +0 -0
  130. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/format.py +0 -0
  131. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/gui/__init__.py +0 -0
  132. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/gui/base.py +0 -0
  133. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/gui/console.py +0 -0
  134. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/gui/desktop.py +0 -0
  135. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/gui/tui.py +0 -0
  136. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/importers/__init__.py +0 -0
  137. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/importers/base.py +0 -0
  138. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/importers/csv.py +0 -0
  139. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/importers/feather.py +0 -0
  140. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/importers/json.py +0 -0
  141. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/importers/ods.py +0 -0
  142. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/importers/xls.py +0 -0
  143. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/__init__.py +0 -0
  144. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/conditions.py +0 -0
  145. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/connect.py +0 -0
  146. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/control.py +0 -0
  147. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/data.py +0 -0
  148. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/debug.py +0 -0
  149. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/dispatch.py +0 -0
  150. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/io.py +0 -0
  151. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/io_export.py +0 -0
  152. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/io_fileops.py +0 -0
  153. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/io_import.py +0 -0
  154. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/io_write.py +0 -0
  155. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/prompt.py +0 -0
  156. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/script_ext.py +0 -0
  157. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/system.py +0 -0
  158. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/metacommands/upsert.py +0 -0
  159. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/models.py +0 -0
  160. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/parser.py +0 -0
  161. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/plugins.py +0 -0
  162. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/py.typed +0 -0
  163. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/script/__init__.py +0 -0
  164. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/script/ast.py +0 -0
  165. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/script/control.py +0 -0
  166. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/script/engine.py +0 -0
  167. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/script/parser.py +0 -0
  168. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/script/variables.py +0 -0
  169. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/state.py +0 -0
  170. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/types.py +0 -0
  171. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/__init__.py +0 -0
  172. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/auth.py +0 -0
  173. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/crypto.py +0 -0
  174. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/datetime.py +0 -0
  175. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/errors.py +0 -0
  176. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/fileio.py +0 -0
  177. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/gui.py +0 -0
  178. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/mail.py +0 -0
  179. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/numeric.py +0 -0
  180. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/regex.py +0 -0
  181. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/strings.py +0 -0
  182. {execsql2-2.16.3 → execsql2-2.16.4}/src/execsql/utils/timer.py +0 -0
  183. {execsql2-2.16.3 → execsql2-2.16.4}/templates/README.md +0 -0
  184. {execsql2-2.16.3 → execsql2-2.16.4}/templates/config_settings.sqlite +0 -0
  185. {execsql2-2.16.3 → execsql2-2.16.4}/templates/example_config_prompt.sql +0 -0
  186. {execsql2-2.16.3 → execsql2-2.16.4}/templates/execsql.conf +0 -0
  187. {execsql2-2.16.3 → execsql2-2.16.4}/templates/make_config_db.sql +0 -0
  188. {execsql2-2.16.3 → execsql2-2.16.4}/templates/md_compare.sql +0 -0
  189. {execsql2-2.16.3 → execsql2-2.16.4}/templates/md_glossary.sql +0 -0
  190. {execsql2-2.16.3 → execsql2-2.16.4}/templates/md_upsert.sql +0 -0
  191. {execsql2-2.16.3 → execsql2-2.16.4}/templates/pg_compare.sql +0 -0
  192. {execsql2-2.16.3 → execsql2-2.16.4}/templates/pg_glossary.sql +0 -0
  193. {execsql2-2.16.3 → execsql2-2.16.4}/templates/pg_upsert.sql +0 -0
  194. {execsql2-2.16.3 → execsql2-2.16.4}/templates/script_template.sql +0 -0
  195. {execsql2-2.16.3 → execsql2-2.16.4}/templates/ss_compare.sql +0 -0
  196. {execsql2-2.16.3 → execsql2-2.16.4}/templates/ss_glossary.sql +0 -0
  197. {execsql2-2.16.3 → execsql2-2.16.4}/templates/ss_upsert.sql +0 -0
  198. {execsql2-2.16.3 → execsql2-2.16.4}/tests/__init__.py +0 -0
  199. {execsql2-2.16.3 → execsql2-2.16.4}/tests/cli/__init__.py +0 -0
  200. {execsql2-2.16.3 → execsql2-2.16.4}/tests/cli/test_cli.py +0 -0
  201. {execsql2-2.16.3 → execsql2-2.16.4}/tests/cli/test_cli_e2e.py +0 -0
  202. {execsql2-2.16.3 → execsql2-2.16.4}/tests/cli/test_cli_run.py +0 -0
  203. {execsql2-2.16.3 → execsql2-2.16.4}/tests/cli/test_lint.py +0 -0
  204. {execsql2-2.16.3 → execsql2-2.16.4}/tests/cli/test_ping.py +0 -0
  205. {execsql2-2.16.3 → execsql2-2.16.4}/tests/cli/test_profile.py +0 -0
  206. {execsql2-2.16.3 → execsql2-2.16.4}/tests/conftest.py +0 -0
  207. {execsql2-2.16.3 → execsql2-2.16.4}/tests/db/__init__.py +0 -0
  208. {execsql2-2.16.3 → execsql2-2.16.4}/tests/db/test_base.py +0 -0
  209. {execsql2-2.16.3 → execsql2-2.16.4}/tests/db/test_db_adapters_mocked.py +0 -0
  210. {execsql2-2.16.3 → execsql2-2.16.4}/tests/db/test_dsn.py +0 -0
  211. {execsql2-2.16.3 → execsql2-2.16.4}/tests/db/test_duckdb.py +0 -0
  212. {execsql2-2.16.3 → execsql2-2.16.4}/tests/db/test_factory.py +0 -0
  213. {execsql2-2.16.3 → execsql2-2.16.4}/tests/db/test_postgres.py +0 -0
  214. {execsql2-2.16.3 → execsql2-2.16.4}/tests/db/test_sqlite.py +0 -0
  215. {execsql2-2.16.3 → execsql2-2.16.4}/tests/db/test_sqlite_extra.py +0 -0
  216. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/__init__.py +0 -0
  217. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_base.py +0 -0
  218. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_db.py +0 -0
  219. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_delimited.py +0 -0
  220. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_duckdb_exporter.py +0 -0
  221. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_exporters.py +0 -0
  222. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_feather.py +0 -0
  223. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_html_extended.py +0 -0
  224. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_html_latex.py +0 -0
  225. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_json.py +0 -0
  226. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_json_extended.py +0 -0
  227. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_latex_extended.py +0 -0
  228. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_markdown.py +0 -0
  229. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_ods.py +0 -0
  230. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_parquet.py +0 -0
  231. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_pretty_extended.py +0 -0
  232. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_raw_extended.py +0 -0
  233. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_sqlite_exporter.py +0 -0
  234. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_templates.py +0 -0
  235. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_templates_extended.py +0 -0
  236. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_values_extended.py +0 -0
  237. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_xls_xlsx.py +0 -0
  238. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_xlsx.py +0 -0
  239. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_xml.py +0 -0
  240. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_yaml.py +0 -0
  241. {execsql2-2.16.3 → execsql2-2.16.4}/tests/exporters/test_zip.py +0 -0
  242. {execsql2-2.16.3 → execsql2-2.16.4}/tests/gui/__init__.py +0 -0
  243. {execsql2-2.16.3 → execsql2-2.16.4}/tests/gui/test_backends.py +0 -0
  244. {execsql2-2.16.3 → execsql2-2.16.4}/tests/gui/test_compare_stats.py +0 -0
  245. {execsql2-2.16.3 → execsql2-2.16.4}/tests/gui/test_compute_row_diffs.py +0 -0
  246. {execsql2-2.16.3 → execsql2-2.16.4}/tests/importers/__init__.py +0 -0
  247. {execsql2-2.16.3 → execsql2-2.16.4}/tests/importers/test_base_extended.py +0 -0
  248. {execsql2-2.16.3 → execsql2-2.16.4}/tests/importers/test_csv_edge_cases.py +0 -0
  249. {execsql2-2.16.3 → execsql2-2.16.4}/tests/importers/test_csv_importer.py +0 -0
  250. {execsql2-2.16.3 → execsql2-2.16.4}/tests/importers/test_feather_importer.py +0 -0
  251. {execsql2-2.16.3 → execsql2-2.16.4}/tests/importers/test_json_importer.py +0 -0
  252. {execsql2-2.16.3 → execsql2-2.16.4}/tests/importers/test_ods_importer.py +0 -0
  253. {execsql2-2.16.3 → execsql2-2.16.4}/tests/importers/test_xls_importer.py +0 -0
  254. {execsql2-2.16.3 → execsql2-2.16.4}/tests/integration/__init__.py +0 -0
  255. {execsql2-2.16.3 → execsql2-2.16.4}/tests/integration/conftest.py +0 -0
  256. {execsql2-2.16.3 → execsql2-2.16.4}/tests/integration/test_dsn.py +0 -0
  257. {execsql2-2.16.3 → execsql2-2.16.4}/tests/integration/test_duckdb.py +0 -0
  258. {execsql2-2.16.3 → execsql2-2.16.4}/tests/integration/test_mysql.py +0 -0
  259. {execsql2-2.16.3 → execsql2-2.16.4}/tests/integration/test_postgres.py +0 -0
  260. {execsql2-2.16.3 → execsql2-2.16.4}/tests/integration/test_sqlite.py +0 -0
  261. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/__init__.py +0 -0
  262. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_assert.py +0 -0
  263. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_breakpoint.py +0 -0
  264. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_connect.py +0 -0
  265. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_io_export.py +0 -0
  266. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_io_import.py +0 -0
  267. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_metacommands.py +0 -0
  268. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_metacommands_connect.py +0 -0
  269. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_metacommands_data.py +0 -0
  270. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_metacommands_extended.py +0 -0
  271. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_metacommands_fileops_extra.py +0 -0
  272. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_metacommands_io.py +0 -0
  273. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_metacommands_io_write_extra.py +0 -0
  274. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_metacommands_script_ext.py +0 -0
  275. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_metacommands_system.py +0 -0
  276. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_metacommands_system_extra.py +0 -0
  277. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_pg_upsert.py +0 -0
  278. {execsql2-2.16.3 → execsql2-2.16.4}/tests/metacommands/test_row_count.py +0 -0
  279. {execsql2-2.16.3 → execsql2-2.16.4}/tests/scripts/__init__.py +0 -0
  280. {execsql2-2.16.3 → execsql2-2.16.4}/tests/scripts/fixtures/control_flow.sql +0 -0
  281. {execsql2-2.16.3 → execsql2-2.16.4}/tests/scripts/fixtures/io_roundtrip.sql +0 -0
  282. {execsql2-2.16.3 → execsql2-2.16.4}/tests/scripts/fixtures/parse_only/parse_tree.sql +0 -0
  283. {execsql2-2.16.3 → execsql2-2.16.4}/tests/scripts/fixtures/smoke.sql +0 -0
  284. {execsql2-2.16.3 → execsql2-2.16.4}/tests/scripts/test_sql_scripts.py +0 -0
  285. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_api.py +0 -0
  286. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_ast.py +0 -0
  287. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_ast_parser.py +0 -0
  288. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_config.py +0 -0
  289. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_config_data.py +0 -0
  290. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_config_extended.py +0 -0
  291. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_debug_repl.py +0 -0
  292. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_engine.py +0 -0
  293. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_error_messages.py +0 -0
  294. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_exceptions.py +0 -0
  295. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_format.py +0 -0
  296. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_mail.py +0 -0
  297. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_models.py +0 -0
  298. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_package.py +0 -0
  299. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_parser.py +0 -0
  300. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_plugins.py +0 -0
  301. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_registry.py +0 -0
  302. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_script.py +0 -0
  303. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_state.py +0 -0
  304. {execsql2-2.16.3 → execsql2-2.16.4}/tests/test_types.py +0 -0
  305. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/__init__.py +0 -0
  306. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_auth.py +0 -0
  307. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_auth_extra.py +0 -0
  308. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_crypto.py +0 -0
  309. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_datetime.py +0 -0
  310. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_errors.py +0 -0
  311. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_errors_extra.py +0 -0
  312. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_fileio.py +0 -0
  313. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_fileio_extra.py +0 -0
  314. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_numeric.py +0 -0
  315. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_regex.py +0 -0
  316. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_strings.py +0 -0
  317. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_timer.py +0 -0
  318. {execsql2-2.16.3 → execsql2-2.16.4}/tests/utils/test_timer_extra.py +0 -0
  319. {execsql2-2.16.3 → execsql2-2.16.4}/zensical.toml +0 -0
@@ -13,6 +13,14 @@ ______________________________________________________________________
13
13
 
14
14
  ______________________________________________________________________
15
15
 
16
+ ## [2.16.4] - 2026-04-30
17
+
18
+ ### Fixed
19
+
20
+ - Forward references in SCRIPT blocks now work: `EXECUTE SCRIPT foo` can appear before `BEGIN SCRIPT foo` in the same file or INCLUDE'd file. The AST executor now pre-scans for all SCRIPT block definitions before execution begins, matching the legacy engine's two-pass behavior.
21
+
22
+ ______________________________________________________________________
23
+
16
24
  ## [2.16.3] - 2026-04-30
17
25
 
18
26
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: execsql2
3
- Version: 2.16.3
3
+ Version: 2.16.4
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
@@ -314,6 +314,7 @@ These are behavioral changes driven by security or correctness issues in the ups
314
314
  | AST executor `~`/`+` variable scoping broken | The AST executor passed `localvars` through function parameters but never pushed `CommandList` frames onto `commandliststack`. Legacy metacommand handlers (`x_sub`, `x_rm_sub`, `xf_sub_defined`, `SUB_LOCAL`, prompt handlers, REPL) access `commandliststack[-1]` for `~` local and `+` outer-scope variables. This caused `~` vars to be invisible to SQL, `SUB_DEFINED(~var)` to always return false, and the REPL `.vars`/`.stack` to show empty state. Fixed by pushing/popping `CommandList` frames in `execute()` and `_execute_script_native()`. |
315
315
  | AST parser INCLUDE quoted paths broken | The AST parser captured the full INCLUDE target including surrounding quotes (`"path"`), but the legacy dispatch regex stripped them. Quoted INCLUDE paths failed with "File does not exist" even when the file was present. Fixed by stripping matched quote pairs in the parser. |
316
316
  | AST parser `BEGIN SCRIPT name(params)` rejected | The regex required whitespace between the script name and parameter list. `BEGIN SCRIPT foo(a,b)` (no space before `(`) silently failed to match, causing the matching `END SCRIPT` to raise "Unmatched END SCRIPT metacommand." Fixed by allowing optional whitespace before the parameter expression. |
317
+ | AST executor forward SCRIPT references broken | The legacy engine registered all `BEGIN SCRIPT` blocks at parse time (two-pass), so `EXECUTE SCRIPT foo` could appear before the `BEGIN SCRIPT foo` definition. The AST executor walked the tree in a single pass, so forward references failed with "There is no SCRIPT named foo." Fixed by adding a pre-registration scan of all SCRIPT blocks before execution begins. |
317
318
 
318
319
  ______________________________________________________________________
319
320
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "execsql2"
7
- version = "2.16.3"
7
+ version = "2.16.4"
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.3"
168
+ current_version = "2.16.4"
169
169
  commit = true
170
170
  tag = true
171
171
  tag_name = "v{new_version}"
@@ -448,6 +448,33 @@ def _execute_batch(
448
448
  ctx.status.batch.end_batch()
449
449
 
450
450
 
451
+ def _pre_register_scripts(ctx: RuntimeContext, nodes: list[Node]) -> None:
452
+ """Pre-scan AST nodes and register all ScriptBlock definitions.
453
+
454
+ The legacy engine used a two-pass approach — parse first (registering all
455
+ BEGIN SCRIPT blocks), then execute. The AST executor walks the tree in a
456
+ single pass, so forward references (EXECUTE SCRIPT before BEGIN SCRIPT)
457
+ would fail. This pre-scan restores compatibility by registering all script
458
+ blocks before execution begins.
459
+
460
+ Only scans the top level and inside IF/ELSE blocks — SCRIPT blocks inside
461
+ LOOPs or other SCRIPTs are not pre-registered (matching legacy behavior
462
+ where nested definitions weren't visible until the enclosing block ran).
463
+ """
464
+ for node in nodes:
465
+ if isinstance(node, ScriptBlock):
466
+ _register_script_block(ctx, node)
467
+ elif isinstance(node, IfBlock):
468
+ # Scripts defined inside IF branches should be registered too,
469
+ # since the legacy parser registered them unconditionally at
470
+ # parse time regardless of the IF condition.
471
+ _pre_register_scripts(ctx, node.body)
472
+ for clause in node.elseif_clauses:
473
+ _pre_register_scripts(ctx, clause.body)
474
+ if node.else_body:
475
+ _pre_register_scripts(ctx, node.else_body)
476
+
477
+
451
478
  def _register_script_block(ctx: RuntimeContext, node: ScriptBlock) -> None:
452
479
  """Register a named SCRIPT block.
453
480
 
@@ -799,6 +826,9 @@ def _execute_include_native(
799
826
  encoding = ctx.conf.script_encoding if ctx.conf else "utf-8"
800
827
  included_tree = parse_script(target, encoding=encoding)
801
828
 
829
+ # Pre-register SCRIPT blocks in the included file so forward references work.
830
+ _pre_register_scripts(ctx, included_tree.body)
831
+
802
832
  # Execute with include-chain tracking
803
833
  ctx.include_chain.append(resolved)
804
834
  try:
@@ -915,6 +945,10 @@ def execute(script: Script, *, ctx: RuntimeContext | None = None) -> None:
915
945
  except (OSError, ValueError):
916
946
  ctx.include_chain.append(script.source)
917
947
  set_static_system_vars(ctx)
948
+ # Pre-register all SCRIPT blocks so forward references work.
949
+ # The legacy engine registered scripts at parse time (two-pass);
950
+ # the AST executor must do an explicit pre-scan.
951
+ _pre_register_scripts(ctx, script.body)
918
952
  # Push a root frame so commandliststack is never empty during AST
919
953
  # execution. This ensures get_subvarset(), current_script_line(),
920
954
  # xf_sub_defined(), the REPL, and all other commandliststack readers
@@ -353,6 +353,32 @@ class TestScriptBlocks:
353
353
  rows = _query_db(tmp_path, "SELECT x FROM t ORDER BY x")
354
354
  assert rows == [(77,), (99,)]
355
355
 
356
+ def test_forward_reference_script(self, tmp_path):
357
+ """EXECUTE SCRIPT before BEGIN SCRIPT (forward reference) works."""
358
+ result = _run_ast(
359
+ "CREATE TABLE t (x INT);\n"
360
+ "-- !x! EXECUTE SCRIPT make_row\n"
361
+ "-- !x! BEGIN SCRIPT make_row\n"
362
+ "INSERT INTO t VALUES (42);\n"
363
+ "-- !x! END SCRIPT\n",
364
+ tmp_path,
365
+ )
366
+ assert result.returncode == 0, result.stderr
367
+ assert _query_db(tmp_path, "SELECT x FROM t") == [(42,)]
368
+
369
+ def test_forward_reference_in_include(self, tmp_path):
370
+ """Forward reference works inside INCLUDE'd files."""
371
+ lib = tmp_path / "lib.sql"
372
+ lib.write_text(
373
+ "-- !x! EXECUTE SCRIPT helper\n-- !x! BEGIN SCRIPT helper\nINSERT INTO t VALUES (99);\n-- !x! END SCRIPT\n",
374
+ )
375
+ result = _run_ast(
376
+ "CREATE TABLE t (x INT);\n-- !x! INCLUDE lib.sql",
377
+ tmp_path,
378
+ )
379
+ assert result.returncode == 0, result.stderr
380
+ assert _query_db(tmp_path, "SELECT x FROM t") == [(99,)]
381
+
356
382
  def test_execute_script_if_exists_missing(self, tmp_path):
357
383
  result = _run_ast(
358
384
  "CREATE TABLE t (x INT);\nINSERT INTO t VALUES (1);\n-- !x! EXECUTE SCRIPT IF EXISTS nonexistent_proc",
@@ -648,7 +648,7 @@ wheels = [
648
648
 
649
649
  [[package]]
650
650
  name = "execsql2"
651
- version = "2.16.3"
651
+ version = "2.16.4"
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