execsql2 2.35.0__tar.gz → 2.37.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (691) hide show
  1. execsql2-2.37.0/.gitattributes +4 -0
  2. {execsql2-2.35.0 → execsql2-2.37.0}/CHANGELOG.md +46 -0
  3. {execsql2-2.35.0 → execsql2-2.37.0}/CONTRIBUTING.md +1 -1
  4. {execsql2-2.35.0 → execsql2-2.37.0}/PKG-INFO +2 -2
  5. {execsql2-2.35.0 → execsql2-2.37.0}/README.md +1 -1
  6. {execsql2-2.35.0 → execsql2-2.37.0}/docs/about/divergence.md +32 -21
  7. {execsql2-2.35.0 → execsql2-2.37.0}/docs/guides/debugging.md +9 -9
  8. {execsql2-2.35.0 → execsql2-2.37.0}/docs/guides/formatter.md +1 -1
  9. {execsql2-2.35.0 → execsql2-2.37.0}/docs/reference/configuration.md +4 -4
  10. {execsql2-2.35.0 → execsql2-2.37.0}/docs/reference/lint.md +9 -1
  11. {execsql2-2.35.0 → execsql2-2.37.0}/docs/reference/metacommands.md +77 -11
  12. {execsql2-2.35.0 → execsql2-2.37.0}/docs/reference/security.md +3 -1
  13. {execsql2-2.35.0 → execsql2-2.37.0}/docs/reference/substitution_vars.md +2 -0
  14. {execsql2-2.35.0 → execsql2-2.37.0}/extras/vscode-execsql/package-lock.json +2 -2
  15. {execsql2-2.35.0 → execsql2-2.37.0}/extras/vscode-execsql/package.json +1 -1
  16. {execsql2-2.35.0 → execsql2-2.37.0}/pyproject.toml +2 -2
  17. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/api.py +16 -8
  18. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/lint.py +54 -6
  19. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/run.py +5 -10
  20. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/data/execsql.conf.template +10 -7
  21. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/base.py +12 -2
  22. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/duckdb.py +8 -1
  23. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/debug/repl.py +2 -2
  24. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/connect.py +10 -9
  25. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/io_fileops.py +6 -3
  26. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/io_write.py +3 -1
  27. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/script_ext.py +13 -10
  28. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/system.py +13 -6
  29. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/script/ast.py +21 -0
  30. execsql2-2.37.0/src/execsql/script/control.py +127 -0
  31. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/script/executor.py +369 -219
  32. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/script/parser.py +102 -52
  33. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/state.py +23 -0
  34. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/errors.py +22 -4
  35. execsql2-2.37.0/src/execsql/utils/sigterm.py +154 -0
  36. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_cli_e2e.py +11 -0
  37. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_lint.py +50 -0
  38. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_manifest.py +1 -1
  39. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_sigterm.py +41 -0
  40. {execsql2-2.35.0 → execsql2-2.37.0}/tests/conftest.py +15 -0
  41. execsql2-2.37.0/tests/corpus/cases/batch_commit_fails/script.sql +21 -0
  42. execsql2-2.37.0/tests/corpus/cases/batch_inner_left_by_break/script.sql +14 -0
  43. execsql2-2.37.0/tests/corpus/cases/batch_left_by_break/script.sql +9 -0
  44. execsql2-2.37.0/tests/corpus/cases/batch_left_by_error/script.sql +12 -0
  45. execsql2-2.37.0/tests/corpus/cases/batch_left_by_halt/script.sql +7 -0
  46. execsql2-2.37.0/tests/corpus/cases/batch_left_under_autocommit_off/script.sql +13 -0
  47. execsql2-2.37.0/tests/corpus/cases/batch_metacommand_sql_fails/script.sql +13 -0
  48. execsql2-2.37.0/tests/corpus/cases/batch_nested_commit_fails/script.sql +15 -0
  49. execsql2-2.37.0/tests/corpus/cases/batch_nested_commit_fails_carry_on/script.sql +22 -0
  50. execsql2-2.37.0/tests/corpus/cases/batch_sql_error_after_end_batch/script.sql +9 -0
  51. execsql2-2.37.0/tests/corpus/cases/batch_statement_fails/script.sql +12 -0
  52. execsql2-2.37.0/tests/corpus/cases/begin_sql_block/script.sql +11 -0
  53. execsql2-2.37.0/tests/corpus/cases/break_at_top_level/script.sql +4 -0
  54. execsql2-2.37.0/tests/corpus/cases/break_in_inline_if/script.sql +8 -0
  55. execsql2-2.37.0/tests/corpus/cases/break_leaves_script_and_include/part.sql +3 -0
  56. execsql2-2.37.0/tests/corpus/cases/break_leaves_script_and_include/script.sql +51 -0
  57. execsql2-2.37.0/tests/corpus/cases/cd_relative_paths/script.sql +5 -0
  58. execsql2-2.37.0/tests/corpus/cases/cd_relative_paths/sub/data.csv +3 -0
  59. execsql2-2.37.0/tests/corpus/cases/commit_fails/script.sql +9 -0
  60. execsql2-2.37.0/tests/corpus/cases/condition_error_block_if/script.sql +20 -0
  61. execsql2-2.37.0/tests/corpus/cases/condition_error_database/script.sql +6 -0
  62. execsql2-2.37.0/tests/corpus/cases/condition_error_script_while/script.sql +8 -0
  63. execsql2-2.37.0/tests/corpus/cases/conditions_more/marker.txt +1 -0
  64. execsql2-2.37.0/tests/corpus/cases/conditions_more/script.sql +30 -0
  65. execsql2-2.37.0/tests/corpus/cases/config_column_headers/duplicate_headers.csv +3 -0
  66. execsql2-2.37.0/tests/corpus/cases/config_column_headers/empty_column.csv +3 -0
  67. execsql2-2.37.0/tests/corpus/cases/config_column_headers/headers.csv +3 -0
  68. execsql2-2.37.0/tests/corpus/cases/config_column_headers/missing_headers.csv +2 -0
  69. execsql2-2.37.0/tests/corpus/cases/config_column_headers/script.sql +16 -0
  70. execsql2-2.37.0/tests/corpus/cases/config_export/script.sql +14 -0
  71. execsql2-2.37.0/tests/corpus/cases/config_import_rows/numbers.csv +3 -0
  72. execsql2-2.37.0/tests/corpus/cases/config_import_rows/rows.csv +5 -0
  73. execsql2-2.37.0/tests/corpus/cases/config_import_rows/script.sql +12 -0
  74. execsql2-2.37.0/tests/corpus/cases/copy_and_import_errors/data.csv +3 -0
  75. execsql2-2.37.0/tests/corpus/cases/copy_and_import_errors/script.sql +13 -0
  76. execsql2-2.37.0/tests/corpus/cases/deferred_substitution/script.sql +11 -0
  77. execsql2-2.37.0/tests/corpus/cases/directive_from_variable/part.sql +1 -0
  78. execsql2-2.37.0/tests/corpus/cases/directive_from_variable/script.sql +14 -0
  79. execsql2-2.37.0/tests/corpus/cases/disconnect_checks/script.sql +38 -0
  80. execsql2-2.37.0/tests/corpus/cases/error_flags/script.sql +13 -0
  81. execsql2-2.37.0/tests/corpus/cases/export_more_formats/script.sql +10 -0
  82. execsql2-2.37.0/tests/corpus/cases/import_file_column/note.txt +2 -0
  83. execsql2-2.37.0/tests/corpus/cases/import_file_column/script.sql +3 -0
  84. execsql2-2.37.0/tests/corpus/cases/inline_directives_and_condition_errors/part.sql +1 -0
  85. execsql2-2.37.0/tests/corpus/cases/inline_directives_and_condition_errors/script.sql +15 -0
  86. execsql2-2.37.0/tests/corpus/cases/local_and_outer_vars/script.sql +14 -0
  87. execsql2-2.37.0/tests/corpus/cases/on_error_halt_execute/script.sql +9 -0
  88. execsql2-2.37.0/tests/corpus/cases/script_extend_and_write/script.sql +15 -0
  89. execsql2-2.37.0/tests/corpus/cases/sub_encrypt_decrypt/script.sql +5 -0
  90. execsql2-2.37.0/tests/corpus/cases/sub_ini/script.sql +5 -0
  91. execsql2-2.37.0/tests/corpus/cases/sub_ini/settings.ini +6 -0
  92. execsql2-2.37.0/tests/corpus/cases/sub_tempfile/script.sql +6 -0
  93. execsql2-2.37.0/tests/corpus/cases/system_vars/script.sql +12 -0
  94. execsql2-2.37.0/tests/corpus/cases/wait_until_and_cancel_halt/script.sql +6 -0
  95. execsql2-2.37.0/tests/corpus/cases/zip_files/note.txt +1 -0
  96. execsql2-2.37.0/tests/corpus/cases/zip_files/script.sql +7 -0
  97. execsql2-2.37.0/tests/corpus/changes.json +1334 -0
  98. execsql2-2.37.0/tests/corpus/results/batch_commit_fails.json +64 -0
  99. execsql2-2.37.0/tests/corpus/results/batch_inner_left_by_break.json +37 -0
  100. execsql2-2.37.0/tests/corpus/results/batch_left_by_break.json +18 -0
  101. execsql2-2.37.0/tests/corpus/results/batch_left_by_error.json +27 -0
  102. execsql2-2.37.0/tests/corpus/results/batch_left_by_halt.json +25 -0
  103. execsql2-2.37.0/tests/corpus/results/batch_left_under_autocommit_off.json +31 -0
  104. execsql2-2.37.0/tests/corpus/results/batch_metacommand_sql_fails.json +33 -0
  105. execsql2-2.37.0/tests/corpus/results/batch_nested_commit_fails.json +36 -0
  106. execsql2-2.37.0/tests/corpus/results/batch_nested_commit_fails_carry_on.json +49 -0
  107. execsql2-2.37.0/tests/corpus/results/batch_sql_error_after_end_batch.json +10 -0
  108. execsql2-2.37.0/tests/corpus/results/batch_statement_fails.json +33 -0
  109. execsql2-2.37.0/tests/corpus/results/begin_sql_block.json +53 -0
  110. execsql2-2.37.0/tests/corpus/results/break_at_top_level.json +10 -0
  111. execsql2-2.37.0/tests/corpus/results/break_in_inline_if.json +10 -0
  112. execsql2-2.37.0/tests/corpus/results/break_leaves_script_and_include.json +10 -0
  113. execsql2-2.37.0/tests/corpus/results/cd_relative_paths.json +46 -0
  114. execsql2-2.37.0/tests/corpus/results/commit_fails.json +43 -0
  115. execsql2-2.37.0/tests/corpus/results/condition_error_block_if.json +10 -0
  116. execsql2-2.37.0/tests/corpus/results/condition_error_database.json +10 -0
  117. execsql2-2.37.0/tests/corpus/results/condition_error_script_while.json +8 -0
  118. execsql2-2.37.0/tests/corpus/results/conditions_more.json +36 -0
  119. execsql2-2.37.0/tests/corpus/results/config_column_headers.json +150 -0
  120. execsql2-2.37.0/tests/corpus/results/config_export.json +47 -0
  121. execsql2-2.37.0/tests/corpus/results/config_import_rows.json +145 -0
  122. execsql2-2.37.0/tests/corpus/results/copy_and_import_errors.json +79 -0
  123. execsql2-2.37.0/tests/corpus/results/deferred_substitution.json +39 -0
  124. execsql2-2.37.0/tests/corpus/results/directive_from_variable.json +10 -0
  125. execsql2-2.37.0/tests/corpus/results/disconnect_checks.json +24 -0
  126. execsql2-2.37.0/tests/corpus/results/error_flags.json +33 -0
  127. execsql2-2.37.0/tests/corpus/results/export_more_formats.json +77 -0
  128. execsql2-2.37.0/tests/corpus/results/import_file_column.json +25 -0
  129. execsql2-2.37.0/tests/corpus/results/inline_directives_and_condition_errors.json +10 -0
  130. execsql2-2.37.0/tests/corpus/results/local_and_outer_vars.json +37 -0
  131. execsql2-2.37.0/tests/corpus/results/on_error_halt_execute.json +27 -0
  132. execsql2-2.37.0/tests/corpus/results/script_extend_and_write.json +40 -0
  133. execsql2-2.37.0/tests/corpus/results/sub_encrypt_decrypt.json +10 -0
  134. execsql2-2.37.0/tests/corpus/results/sub_ini.json +10 -0
  135. execsql2-2.37.0/tests/corpus/results/sub_tempfile.json +10 -0
  136. execsql2-2.37.0/tests/corpus/results/system_vars.json +39 -0
  137. execsql2-2.37.0/tests/corpus/results/wait_until_and_cancel_halt.json +10 -0
  138. execsql2-2.37.0/tests/corpus/results/zip_files.json +51 -0
  139. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/runner.py +19 -1
  140. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_transactions.py +67 -2
  141. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands.py +2 -2
  142. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_extended.py +3 -5
  143. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_fileops_extra.py +1 -1
  144. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_io.py +1 -1
  145. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_script_ext.py +1 -1
  146. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_system.py +42 -17
  147. execsql2-2.37.0/tests/test_break.py +80 -0
  148. execsql2-2.37.0/tests/test_disconnect.py +130 -0
  149. execsql2-2.37.0/tests/test_end_batch_commit.py +268 -0
  150. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_error_messages.py +5 -5
  151. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_executor.py +11 -11
  152. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_executor_inprocess.py +5 -0
  153. execsql2-2.37.0/tests/test_failed_commit.py +162 -0
  154. execsql2-2.37.0/tests/test_include_errors.py +349 -0
  155. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_interactive.py +28 -1
  156. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_script.py +117 -0
  157. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_state.py +23 -0
  158. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_errors_extra.py +38 -0
  159. execsql2-2.37.0/tests/utils/test_sigterm.py +319 -0
  160. {execsql2-2.35.0 → execsql2-2.37.0}/uv.lock +1 -1
  161. execsql2-2.35.0/src/execsql/script/control.py +0 -67
  162. execsql2-2.35.0/tests/corpus/changes.json +0 -513
  163. {execsql2-2.35.0 → execsql2-2.37.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  164. {execsql2-2.35.0 → execsql2-2.37.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  165. {execsql2-2.35.0 → execsql2-2.37.0}/.github/dependabot.yml +0 -0
  166. {execsql2-2.35.0 → execsql2-2.37.0}/.github/workflows/ci-cd.yml +0 -0
  167. {execsql2-2.35.0 → execsql2-2.37.0}/.gitignore +0 -0
  168. {execsql2-2.35.0 → execsql2-2.37.0}/.pre-commit-config.yaml +0 -0
  169. {execsql2-2.35.0 → execsql2-2.37.0}/.pre-commit-hooks.yaml +0 -0
  170. {execsql2-2.35.0 → execsql2-2.37.0}/.python-version +0 -0
  171. {execsql2-2.35.0 → execsql2-2.37.0}/.readthedocs.yaml +0 -0
  172. {execsql2-2.35.0 → execsql2-2.37.0}/LICENSE.txt +0 -0
  173. {execsql2-2.35.0 → execsql2-2.37.0}/NOTICE +0 -0
  174. {execsql2-2.35.0 → execsql2-2.37.0}/SECURITY.md +0 -0
  175. {execsql2-2.35.0 → execsql2-2.37.0}/docs/about/contributors.md +0 -0
  176. {execsql2-2.35.0 → execsql2-2.37.0}/docs/about/copyright.md +0 -0
  177. {execsql2-2.35.0 → execsql2-2.37.0}/docs/api/cli.md +0 -0
  178. {execsql2-2.35.0 → execsql2-2.37.0}/docs/api/db.md +0 -0
  179. {execsql2-2.35.0 → execsql2-2.37.0}/docs/api/exporters.md +0 -0
  180. {execsql2-2.35.0 → execsql2-2.37.0}/docs/api/importers.md +0 -0
  181. {execsql2-2.35.0 → execsql2-2.37.0}/docs/api/index.md +0 -0
  182. {execsql2-2.35.0 → execsql2-2.37.0}/docs/api/metacommands.md +0 -0
  183. {execsql2-2.35.0 → execsql2-2.37.0}/docs/dev/adding_db_adapters.md +0 -0
  184. {execsql2-2.35.0 → execsql2-2.37.0}/docs/dev/adding_exporters.md +0 -0
  185. {execsql2-2.35.0 → execsql2-2.37.0}/docs/dev/adding_importers.md +0 -0
  186. {execsql2-2.35.0 → execsql2-2.37.0}/docs/dev/adding_metacommands.md +0 -0
  187. {execsql2-2.35.0 → execsql2-2.37.0}/docs/dev/architecture.md +0 -0
  188. {execsql2-2.35.0 → execsql2-2.37.0}/docs/dev/releasing.md +0 -0
  189. {execsql2-2.35.0 → execsql2-2.37.0}/docs/getting-started/installation.md +0 -0
  190. {execsql2-2.35.0 → execsql2-2.37.0}/docs/getting-started/requirements.md +0 -0
  191. {execsql2-2.35.0 → execsql2-2.37.0}/docs/getting-started/syntax.md +0 -0
  192. {execsql2-2.35.0 → execsql2-2.37.0}/docs/guides/documentation.md +0 -0
  193. {execsql2-2.35.0 → execsql2-2.37.0}/docs/guides/editors.md +0 -0
  194. {execsql2-2.35.0 → execsql2-2.37.0}/docs/guides/encoding.md +0 -0
  195. {execsql2-2.35.0 → execsql2-2.37.0}/docs/guides/examples.md +0 -0
  196. {execsql2-2.35.0 → execsql2-2.37.0}/docs/guides/logging.md +0 -0
  197. {execsql2-2.35.0 → execsql2-2.37.0}/docs/guides/sql_syntax.md +0 -0
  198. {execsql2-2.35.0 → execsql2-2.37.0}/docs/guides/usage.md +0 -0
  199. {execsql2-2.35.0 → execsql2-2.37.0}/docs/guides/using_scripts.md +0 -0
  200. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/Compare_planets.png +0 -0
  201. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/actions.png +0 -0
  202. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/actions2.png +0 -0
  203. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/checkboxes.png +0 -0
  204. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/connect.png +0 -0
  205. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/data_error1_screenshot.jpg +0 -0
  206. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/execsql_logo_01.png +0 -0
  207. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/fatals.png +0 -0
  208. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/pause_terminal_sm.png +0 -0
  209. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/set_build_commands.jpg +0 -0
  210. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/unit_conversions_029.png +0 -0
  211. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/unmatched.png +0 -0
  212. {execsql2-2.35.0 → execsql2-2.37.0}/docs/images/vim_execsql_highlight.png +0 -0
  213. {execsql2-2.35.0 → execsql2-2.37.0}/docs/index.md +0 -0
  214. {execsql2-2.35.0 → execsql2-2.37.0}/docs/templates/compare.md +0 -0
  215. {execsql2-2.35.0 → execsql2-2.37.0}/docs/templates/glossary.md +0 -0
  216. {execsql2-2.35.0 → execsql2-2.37.0}/docs/templates/index.md +0 -0
  217. {execsql2-2.35.0 → execsql2-2.37.0}/docs/templates/upsert.md +0 -0
  218. {execsql2-2.35.0 → execsql2-2.37.0}/extras/plugin-template/README.md +0 -0
  219. {execsql2-2.35.0 → execsql2-2.37.0}/extras/plugin-template/pyproject.toml +0 -0
  220. {execsql2-2.35.0 → execsql2-2.37.0}/extras/plugin-template/src/execsql_plugin_YOURNAME/__init__.py +0 -0
  221. {execsql2-2.35.0 → execsql2-2.37.0}/extras/plugin-template/tests/test_plugin.py.example +0 -0
  222. {execsql2-2.35.0 → execsql2-2.37.0}/extras/vscode-execsql/.vscodeignore +0 -0
  223. {execsql2-2.35.0 → execsql2-2.37.0}/extras/vscode-execsql/LICENSE.txt +0 -0
  224. {execsql2-2.35.0 → execsql2-2.37.0}/extras/vscode-execsql/README.md +0 -0
  225. {execsql2-2.35.0 → execsql2-2.37.0}/extras/vscode-execsql/extension.js +0 -0
  226. {execsql2-2.35.0 → execsql2-2.37.0}/extras/vscode-execsql/icon.png +0 -0
  227. {execsql2-2.35.0 → execsql2-2.37.0}/extras/vscode-execsql/syntaxes/execsql.tmLanguage.json +0 -0
  228. {execsql2-2.35.0 → execsql2-2.37.0}/justfile +0 -0
  229. {execsql2-2.35.0 → execsql2-2.37.0}/scripts/benchmarks/README.md +0 -0
  230. {execsql2-2.35.0 → execsql2-2.37.0}/scripts/benchmarks/results/.gitignore +0 -0
  231. {execsql2-2.35.0 → execsql2-2.37.0}/scripts/benchmarks/run_benchmarks.py +0 -0
  232. {execsql2-2.35.0 → execsql2-2.37.0}/scripts/generate_vscode_grammar.py +0 -0
  233. {execsql2-2.35.0 → execsql2-2.37.0}/scripts/release_notes.py +0 -0
  234. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/__init__.py +0 -0
  235. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/__main__.py +0 -0
  236. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/__init__.py +0 -0
  237. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/application.py +0 -0
  238. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/commands/__init__.py +0 -0
  239. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/commands/config.py +0 -0
  240. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/commands/format.py +0 -0
  241. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/commands/init.py +0 -0
  242. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/commands/lint.py +0 -0
  243. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/commands/listing.py +0 -0
  244. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/commands/lsp.py +0 -0
  245. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/commands/run.py +0 -0
  246. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/dispatch.py +0 -0
  247. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/dsn.py +0 -0
  248. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/help.py +0 -0
  249. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/cli/options.py +0 -0
  250. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/config.py +0 -0
  251. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/config_validation.py +0 -0
  252. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/data/__init__.py +0 -0
  253. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/data/script_header.sql +0 -0
  254. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/__init__.py +0 -0
  255. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/access.py +0 -0
  256. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/dsn.py +0 -0
  257. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/factory.py +0 -0
  258. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/firebird.py +0 -0
  259. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/mysql.py +0 -0
  260. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/odbc.py +0 -0
  261. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/oracle.py +0 -0
  262. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/postgres.py +0 -0
  263. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/sqlite.py +0 -0
  264. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/sqlserver.py +0 -0
  265. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/target_types.py +0 -0
  266. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/db/tiers.py +0 -0
  267. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/debug/__init__.py +0 -0
  268. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exceptions.py +0 -0
  269. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/__init__.py +0 -0
  270. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/base.py +0 -0
  271. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/delimited.py +0 -0
  272. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/duckdb.py +0 -0
  273. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/feather.py +0 -0
  274. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/html.py +0 -0
  275. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/json.py +0 -0
  276. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/latex.py +0 -0
  277. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/markdown.py +0 -0
  278. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/ods.py +0 -0
  279. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/parquet.py +0 -0
  280. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/pretty.py +0 -0
  281. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/protocol.py +0 -0
  282. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/raw.py +0 -0
  283. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/sqlite.py +0 -0
  284. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/templates.py +0 -0
  285. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/values.py +0 -0
  286. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/xls.py +0 -0
  287. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/xlsx.py +0 -0
  288. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/xml.py +0 -0
  289. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/yaml.py +0 -0
  290. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/exporters/zip.py +0 -0
  291. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/format.py +0 -0
  292. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/gui/__init__.py +0 -0
  293. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/gui/base.py +0 -0
  294. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/gui/console.py +0 -0
  295. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/gui/desktop.py +0 -0
  296. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/gui/tui.py +0 -0
  297. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/importers/__init__.py +0 -0
  298. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/importers/base.py +0 -0
  299. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/importers/csv.py +0 -0
  300. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/importers/feather.py +0 -0
  301. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/importers/json.py +0 -0
  302. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/importers/ods.py +0 -0
  303. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/importers/xls.py +0 -0
  304. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/interactive.py +0 -0
  305. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/__init__.py +0 -0
  306. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/_util.py +0 -0
  307. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/cache.py +0 -0
  308. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/code_actions.py +0 -0
  309. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/completion.py +0 -0
  310. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/diagnostics.py +0 -0
  311. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/document.py +0 -0
  312. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/folding.py +0 -0
  313. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/formatting.py +0 -0
  314. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/hover.py +0 -0
  315. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/navigation.py +0 -0
  316. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/rename.py +0 -0
  317. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/lsp/server.py +0 -0
  318. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/manifest.py +0 -0
  319. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/__init__.py +0 -0
  320. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/conditions.py +0 -0
  321. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/control.py +0 -0
  322. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/data.py +0 -0
  323. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/debug.py +0 -0
  324. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/dispatch.py +0 -0
  325. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/effects.py +0 -0
  326. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/io.py +0 -0
  327. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/io_export.py +0 -0
  328. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/io_import.py +0 -0
  329. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/prompt.py +0 -0
  330. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/reference.py +0 -0
  331. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/metacommands/upsert.py +0 -0
  332. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/models.py +0 -0
  333. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/parser.py +0 -0
  334. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/plugins.py +0 -0
  335. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/py.typed +0 -0
  336. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/script/__init__.py +0 -0
  337. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/script/engine.py +0 -0
  338. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/script/variables.py +0 -0
  339. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/state.pyi +0 -0
  340. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/types.py +0 -0
  341. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/__init__.py +0 -0
  342. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/auth.py +0 -0
  343. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/color.py +0 -0
  344. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/crypto.py +0 -0
  345. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/datetime.py +0 -0
  346. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/fileio.py +0 -0
  347. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/gui.py +0 -0
  348. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/mail.py +0 -0
  349. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/numeric.py +0 -0
  350. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/paths.py +0 -0
  351. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/regex.py +0 -0
  352. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/strings.py +0 -0
  353. {execsql2-2.35.0 → execsql2-2.37.0}/src/execsql/utils/timer.py +0 -0
  354. {execsql2-2.35.0 → execsql2-2.37.0}/templates/README.md +0 -0
  355. {execsql2-2.35.0 → execsql2-2.37.0}/templates/config_settings.sqlite +0 -0
  356. {execsql2-2.35.0 → execsql2-2.37.0}/templates/example_config_prompt.sql +0 -0
  357. {execsql2-2.35.0 → execsql2-2.37.0}/templates/make_config_db.sql +0 -0
  358. {execsql2-2.35.0 → execsql2-2.37.0}/templates/md_compare.sql +0 -0
  359. {execsql2-2.35.0 → execsql2-2.37.0}/templates/md_glossary.sql +0 -0
  360. {execsql2-2.35.0 → execsql2-2.37.0}/templates/md_upsert.sql +0 -0
  361. {execsql2-2.35.0 → execsql2-2.37.0}/templates/pg_compare.sql +0 -0
  362. {execsql2-2.35.0 → execsql2-2.37.0}/templates/pg_glossary.sql +0 -0
  363. {execsql2-2.35.0 → execsql2-2.37.0}/templates/script_template.sql +0 -0
  364. {execsql2-2.35.0 → execsql2-2.37.0}/templates/ss_compare.sql +0 -0
  365. {execsql2-2.35.0 → execsql2-2.37.0}/templates/ss_glossary.sql +0 -0
  366. {execsql2-2.35.0 → execsql2-2.37.0}/templates/ss_upsert.sql +0 -0
  367. {execsql2-2.35.0 → execsql2-2.37.0}/tests/__init__.py +0 -0
  368. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/__init__.py +0 -0
  369. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_cli.py +0 -0
  370. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_cli_run.py +0 -0
  371. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_cli_surface.py +0 -0
  372. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_commands.py +0 -0
  373. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_config_validate.py +0 -0
  374. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_dispatch.py +0 -0
  375. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_error_location.py +0 -0
  376. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_init.py +0 -0
  377. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_lint_fixtures.py +0 -0
  378. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_log_exit_record.py +0 -0
  379. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_ping.py +0 -0
  380. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_profile.py +0 -0
  381. {execsql2-2.35.0 → execsql2-2.37.0}/tests/cli/test_undeclared_imports.py +0 -0
  382. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/__init__.py +0 -0
  383. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/batch_and_autocommit/script.sql +0 -0
  384. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/boolean_and_empty_config/data.csv +0 -0
  385. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/boolean_and_empty_config/script.sql +0 -0
  386. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/copy_between_databases/script.sql +0 -0
  387. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/counters/script.sql +0 -0
  388. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/decimal_digits/long.csv +0 -0
  389. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/decimal_digits/script.sql +0 -0
  390. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/decimal_digits/short.csv +0 -0
  391. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/error_halt_off/script.sql +0 -0
  392. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/error_stops_script/script.sql +0 -0
  393. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/execute_script_args/script.sql +0 -0
  394. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/export_query_append/script.sql +0 -0
  395. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/export_structured_formats/script.sql +0 -0
  396. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/export_text_formats/script.sql +0 -0
  397. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/halt_exit_status/script.sql +0 -0
  398. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/if_conditions/script.sql +0 -0
  399. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/import_csv_existing/data.csv +0 -0
  400. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/import_csv_existing/script.sql +0 -0
  401. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/import_csv_new/data.csv +0 -0
  402. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/import_csv_new/data.tsv +0 -0
  403. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/import_csv_new/script.sql +0 -0
  404. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/include_file/part.sql +0 -0
  405. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/include_file/script.sql +0 -0
  406. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/loop_while_until/script.sql +0 -0
  407. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/on_error_halt_write/script.sql +0 -0
  408. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/select_sub_subdata/script.sql +0 -0
  409. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/sub_backslash/script.sql +0 -0
  410. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/sub_basic/script.sql +0 -0
  411. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/sub_quoting/script.sql +0 -0
  412. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/sub_quoting_upstream_idiom/script.sql +0 -0
  413. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/unsubstituted_warning/script.sql +0 -0
  414. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/write_console/script.sql +0 -0
  415. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/write_create_table/data.csv +0 -0
  416. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/cases/write_create_table/script.sql +0 -0
  417. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/record.py +0 -0
  418. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/batch_and_autocommit.json +0 -0
  419. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/boolean_and_empty_config.json +0 -0
  420. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/copy_between_databases.json +0 -0
  421. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/counters.json +0 -0
  422. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/decimal_digits.json +0 -0
  423. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/error_halt_off.json +0 -0
  424. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/error_stops_script.json +0 -0
  425. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/execute_script_args.json +0 -0
  426. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/export_query_append.json +0 -0
  427. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/export_structured_formats.json +0 -0
  428. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/export_text_formats.json +0 -0
  429. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/halt_exit_status.json +0 -0
  430. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/if_conditions.json +0 -0
  431. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/import_csv_existing.json +0 -0
  432. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/import_csv_new.json +0 -0
  433. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/include_file.json +0 -0
  434. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/loop_while_until.json +0 -0
  435. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/on_error_halt_write.json +0 -0
  436. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/select_sub_subdata.json +0 -0
  437. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/sub_backslash.json +0 -0
  438. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/sub_basic.json +0 -0
  439. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/sub_quoting.json +0 -0
  440. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/sub_quoting_upstream_idiom.json +0 -0
  441. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/unsubstituted_warning.json +0 -0
  442. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/write_console.json +0 -0
  443. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/results/write_create_table.json +0 -0
  444. {execsql2-2.35.0 → execsql2-2.37.0}/tests/corpus/test_script_corpus.py +0 -0
  445. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/existing_table_loads/changes.json +0 -0
  446. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/existing_table_loads/duckdb.json +0 -0
  447. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/existing_table_loads/mysql.json +0 -0
  448. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/existing_table_loads/mysql_files.json +0 -0
  449. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/existing_table_loads/postgres.json +0 -0
  450. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/existing_table_loads/postgres_files.json +0 -0
  451. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/existing_table_loads/sqlite.json +0 -0
  452. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/existing_table_loads/sqlserver.json +0 -0
  453. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/formatter_shapes/comment_anchoring.sql +0 -0
  454. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/formatter_shapes/escapes_and_literals.sql +0 -0
  455. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/formatter_shapes/substitution_and_metacommands.sql +0 -0
  456. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/formatter_shapes/unparsable_sql.sql +0 -0
  457. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/lint/conditions_and_blocks.sql +0 -0
  458. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/lint/does_not_parse.sql +0 -0
  459. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/lint/every_metacommand.sql +0 -0
  460. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/lint/invalid.sql +0 -0
  461. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/ods/libreoffice.fods +0 -0
  462. {execsql2-2.35.0 → execsql2-2.37.0}/tests/data/ods/libreoffice.ods +0 -0
  463. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/__init__.py +0 -0
  464. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/conftest.py +0 -0
  465. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_access_windows.py +0 -0
  466. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_base.py +0 -0
  467. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_bulk_inserts.py +0 -0
  468. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_copy_new.py +0 -0
  469. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_db_adapters_mocked.py +0 -0
  470. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_db_adapters_mocked_extra.py +0 -0
  471. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_dsn.py +0 -0
  472. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_duckdb.py +0 -0
  473. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_existing_table_loads.py +0 -0
  474. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_factory.py +0 -0
  475. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_factory_postgres_encoding.py +0 -0
  476. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_import_atomic.py +0 -0
  477. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_import_replacement_quoted.py +0 -0
  478. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_import_short_rows.py +0 -0
  479. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_import_timezones.py +0 -0
  480. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_mysql_case_folding.py +0 -0
  481. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_mysql_inprocess.py +0 -0
  482. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_mysql_trailing_blank_lines.py +0 -0
  483. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_new_table_checks.py +0 -0
  484. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_odbc_fresh_sessions.py +0 -0
  485. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_oracle_driver.py +0 -0
  486. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_postgres.py +0 -0
  487. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_postgres_inprocess.py +0 -0
  488. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_quoted_substitution_roundtrip.py +0 -0
  489. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_replacement_missing_table.py +0 -0
  490. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_roundtrip_adapters.py +0 -0
  491. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_sqlite.py +0 -0
  492. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_sqlite_extra.py +0 -0
  493. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_sqlserver_driver18.py +0 -0
  494. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_sqlserver_inprocess.py +0 -0
  495. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_target_types.py +0 -0
  496. {execsql2-2.35.0 → execsql2-2.37.0}/tests/db/test_tiers.py +0 -0
  497. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/__init__.py +0 -0
  498. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/conftest.py +0 -0
  499. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_base.py +0 -0
  500. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_db.py +0 -0
  501. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_delimited.py +0 -0
  502. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_duckdb_exporter.py +0 -0
  503. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_exporters.py +0 -0
  504. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_feather.py +0 -0
  505. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_html_extended.py +0 -0
  506. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_html_latex.py +0 -0
  507. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_json.py +0 -0
  508. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_json_extended.py +0 -0
  509. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_jsonl.py +0 -0
  510. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_latex_extended.py +0 -0
  511. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_markdown.py +0 -0
  512. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_ods.py +0 -0
  513. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_ods_export.py +0 -0
  514. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_parquet.py +0 -0
  515. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_pretty_extended.py +0 -0
  516. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_raw_extended.py +0 -0
  517. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_columnar.py +0 -0
  518. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_dbfile.py +0 -0
  519. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_delimited.py +0 -0
  520. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_json.py +0 -0
  521. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_latex_xml.py +0 -0
  522. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_markup.py +0 -0
  523. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_ods.py +0 -0
  524. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_pretty_raw.py +0 -0
  525. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_template.py +0 -0
  526. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_values.py +0 -0
  527. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_xlsx.py +0 -0
  528. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_sqlite_exporter.py +0 -0
  529. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_templates.py +0 -0
  530. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_templates_extended.py +0 -0
  531. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_values_extended.py +0 -0
  532. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_values_roundtrip.py +0 -0
  533. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_xls_xlsx.py +0 -0
  534. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_xlsx.py +0 -0
  535. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_xml.py +0 -0
  536. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_yaml.py +0 -0
  537. {execsql2-2.35.0 → execsql2-2.37.0}/tests/exporters/test_zip.py +0 -0
  538. {execsql2-2.35.0 → execsql2-2.37.0}/tests/gui/__init__.py +0 -0
  539. {execsql2-2.35.0 → execsql2-2.37.0}/tests/gui/test_backends.py +0 -0
  540. {execsql2-2.35.0 → execsql2-2.37.0}/tests/gui/test_backends_extended.py +0 -0
  541. {execsql2-2.35.0 → execsql2-2.37.0}/tests/gui/test_compare_stats.py +0 -0
  542. {execsql2-2.35.0 → execsql2-2.37.0}/tests/gui/test_compute_row_diffs.py +0 -0
  543. {execsql2-2.35.0 → execsql2-2.37.0}/tests/gui/test_desktop_dialogs.py +0 -0
  544. {execsql2-2.35.0 → execsql2-2.37.0}/tests/gui/test_format_table.py +0 -0
  545. {execsql2-2.35.0 → execsql2-2.37.0}/tests/gui/test_tui_pilot.py +0 -0
  546. {execsql2-2.35.0 → execsql2-2.37.0}/tests/gui/test_tui_pilot_complex.py +0 -0
  547. {execsql2-2.35.0 → execsql2-2.37.0}/tests/gui/test_utils_gui_extended.py +0 -0
  548. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/__init__.py +0 -0
  549. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/conftest.py +0 -0
  550. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/test_base_extended.py +0 -0
  551. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/test_csv_blank_lines.py +0 -0
  552. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/test_csv_edge_cases.py +0 -0
  553. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/test_csv_importer.py +0 -0
  554. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/test_feather_importer.py +0 -0
  555. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/test_json_importer.py +0 -0
  556. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/test_ods_importer.py +0 -0
  557. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/test_ods_values.py +0 -0
  558. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/test_roundtrip_csv.py +0 -0
  559. {execsql2-2.35.0 → execsql2-2.37.0}/tests/importers/test_xls_importer.py +0 -0
  560. {execsql2-2.35.0 → execsql2-2.37.0}/tests/integration/__init__.py +0 -0
  561. {execsql2-2.35.0 → execsql2-2.37.0}/tests/integration/conftest.py +0 -0
  562. {execsql2-2.35.0 → execsql2-2.37.0}/tests/integration/test_dsn.py +0 -0
  563. {execsql2-2.35.0 → execsql2-2.37.0}/tests/integration/test_duckdb.py +0 -0
  564. {execsql2-2.35.0 → execsql2-2.37.0}/tests/integration/test_mysql.py +0 -0
  565. {execsql2-2.35.0 → execsql2-2.37.0}/tests/integration/test_postgres.py +0 -0
  566. {execsql2-2.35.0 → execsql2-2.37.0}/tests/integration/test_sqlite.py +0 -0
  567. {execsql2-2.35.0 → execsql2-2.37.0}/tests/live_db.py +0 -0
  568. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/__init__.py +0 -0
  569. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_cache.py +0 -0
  570. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_code_actions.py +0 -0
  571. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_completion.py +0 -0
  572. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_diagnostics.py +0 -0
  573. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_document.py +0 -0
  574. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_folding.py +0 -0
  575. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_formatting.py +0 -0
  576. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_hover.py +0 -0
  577. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_lsp_command.py +0 -0
  578. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_navigation.py +0 -0
  579. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_rename.py +0 -0
  580. {execsql2-2.35.0 → execsql2-2.37.0}/tests/lsp/test_server.py +0 -0
  581. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/__init__.py +0 -0
  582. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/conftest.py +0 -0
  583. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_assert.py +0 -0
  584. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_breakpoint.py +0 -0
  585. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_conditions_extra.py +0 -0
  586. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_connect.py +0 -0
  587. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_io_export.py +0 -0
  588. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_io_import.py +0 -0
  589. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_connect.py +0 -0
  590. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_data.py +0 -0
  591. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_io_write_extra.py +0 -0
  592. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_system_extra.py +0 -0
  593. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_pg_upsert.py +0 -0
  594. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_prompt.py +0 -0
  595. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_row_count.py +0 -0
  596. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_serve_output.py +0 -0
  597. {execsql2-2.35.0 → execsql2-2.37.0}/tests/metacommands/test_show_scripts.py +0 -0
  598. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/__init__.py +0 -0
  599. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/audit_lint_bad.sql +0 -0
  600. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/audit_smoke/sample.json +0 -0
  601. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/audit_smoke/sample.jsonl +0 -0
  602. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/audit_smoke.sql +0 -0
  603. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/config_runtime.sql +0 -0
  604. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/control_flow.sql +0 -0
  605. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/counters_and_locals.sql +0 -0
  606. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/error_handling.sql +0 -0
  607. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/import_options/has_comments.csv +0 -0
  608. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/import_options.sql +0 -0
  609. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/includes/helper.sql +0 -0
  610. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/includes.sql +0 -0
  611. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/io_formats.sql +0 -0
  612. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/io_roundtrip.sql +0 -0
  613. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/multi_db.sql +0 -0
  614. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/parquet_feather_roundtrip.sql +0 -0
  615. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/parse_only/parse_tree.sql +0 -0
  616. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/predicates.sql +0 -0
  617. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/scripts.sql +0 -0
  618. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/smoke.sql +0 -0
  619. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/subroutine_loops.sql +0 -0
  620. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/subvars_advanced.sql +0 -0
  621. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/template_export/greeting.tmpl +0 -0
  622. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/template_export.sql +0 -0
  623. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/timer.sql +0 -0
  624. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/transactions.sql +0 -0
  625. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/write_create_table.sql +0 -0
  626. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/fixtures/xlsx_ods_roundtrip.sql +0 -0
  627. {execsql2-2.35.0 → execsql2-2.37.0}/tests/scripts/test_sql_scripts.py +0 -0
  628. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/__init__.py +0 -0
  629. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_env_detection.py +0 -0
  630. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_expansion_bomb.py +0 -0
  631. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_import_regex_hardening.py +0 -0
  632. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_log_redaction.py +0 -0
  633. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_log_secrets.py +0 -0
  634. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_network_paths.py +0 -0
  635. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_odbc_connection_strings.py +0 -0
  636. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_odbc_injection.py +0 -0
  637. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_path_containment.py +0 -0
  638. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_substitution_injection.py +0 -0
  639. {execsql2-2.35.0 → execsql2-2.37.0}/tests/security/test_zip_bomb.py +0 -0
  640. {execsql2-2.35.0 → execsql2-2.37.0}/tests/templates/__init__.py +0 -0
  641. {execsql2-2.35.0 → execsql2-2.37.0}/tests/templates/conftest.py +0 -0
  642. {execsql2-2.35.0 → execsql2-2.37.0}/tests/templates/test_compare.py +0 -0
  643. {execsql2-2.35.0 → execsql2-2.37.0}/tests/templates/test_glossary.py +0 -0
  644. {execsql2-2.35.0 → execsql2-2.37.0}/tests/templates/test_static.py +0 -0
  645. {execsql2-2.35.0 → execsql2-2.37.0}/tests/templates/test_upsert.py +0 -0
  646. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_api.py +0 -0
  647. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_api_errors.py +0 -0
  648. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_api_extended.py +0 -0
  649. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_api_filewriter.py +0 -0
  650. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_api_isolation.py +0 -0
  651. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_api_subprocess.py +0 -0
  652. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_ast.py +0 -0
  653. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_ast_parser.py +0 -0
  654. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_bundled_templates.py +0 -0
  655. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_config.py +0 -0
  656. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_config_data.py +0 -0
  657. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_config_extended.py +0 -0
  658. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_date_inference.py +0 -0
  659. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_debug_repl.py +0 -0
  660. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_engine.py +0 -0
  661. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_exceptions.py +0 -0
  662. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_format.py +0 -0
  663. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_mail.py +0 -0
  664. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_metacommand_errors.py +0 -0
  665. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_models.py +0 -0
  666. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_package.py +0 -0
  667. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_parser.py +0 -0
  668. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_parser_params.py +0 -0
  669. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_plugins.py +0 -0
  670. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_reference.py +0 -0
  671. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_registry.py +0 -0
  672. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_release_notes.py +0 -0
  673. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_tooling_versions.py +0 -0
  674. {execsql2-2.35.0 → execsql2-2.37.0}/tests/test_types.py +0 -0
  675. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/__init__.py +0 -0
  676. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_auth.py +0 -0
  677. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_auth_extra.py +0 -0
  678. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_crypto.py +0 -0
  679. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_datetime.py +0 -0
  680. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_encodedfile_context.py +0 -0
  681. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_errors.py +0 -0
  682. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_fileio.py +0 -0
  683. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_fileio_extra.py +0 -0
  684. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_keyring_rules.py +0 -0
  685. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_mail_tls.py +0 -0
  686. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_numeric.py +0 -0
  687. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_regex.py +0 -0
  688. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_strings.py +0 -0
  689. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_timer.py +0 -0
  690. {execsql2-2.35.0 → execsql2-2.37.0}/tests/utils/test_timer_extra.py +0 -0
  691. {execsql2-2.35.0 → execsql2-2.37.0}/zensical.toml +0 -0
@@ -0,0 +1,4 @@
1
+ # Corpus inputs are compared byte for byte with upstream's recorded results
2
+ # (IMPORT_FILE stores a file's raw bytes), so Git must not convert their line
3
+ # endings on checkout.
4
+ tests/corpus/cases/** -text
@@ -13,6 +13,52 @@ ______________________________________________________________________
13
13
 
14
14
  ______________________________________________________________________
15
15
 
16
+ ## [2.37.0] - 2026-10-23
17
+
18
+ ### Changed
19
+
20
+ - **A failed commit at `END BATCH`** is an SQL error on the `END BATCH` line, which `ERROR_HALT` governs; it was reported as an uncaught exception on a line of execsql's own source and always stopped the run. With `ERROR_HALT OFF` the script now carries on: test `SQL_ERROR()` right after `END BATCH`.
21
+ - **`SQL_ERROR()` right after `END BATCH`** says whether the batch's commit failed: `END BATCH` clears it first, as an SQL statement does. It kept the value left by the last statement run before it.
22
+ - **Anything that fails inside `BEGIN BATCH`**, an SQL statement, a metacommand or a metacommand's SQL, keeps the batch from being committed: `END BATCH` rolls it back and reports an SQL error, which stops the run if `ERROR_HALT` is `ON` there. The batch's statements after a failure were committed, even when a failed statement had already rolled back the ones before it. Put a statement or metacommand whose failure the script handles outside the batch.
23
+ - **A batch around one whose commit failed** is not committed at its own `END BATCH`, nor is any batch opened inside it afterwards, and `ROLLBACK BATCH` does not undo this; put work that must survive after the outermost `END BATCH`.
24
+ - **`DISCONNECT` inside `BEGIN BATCH`** refuses a database the batch has used, as documented: the run halts and the batch is rolled back, or with `METACOMMAND_ERROR_HALT OFF` the connection stays open and `END BATCH` rolls the batch back; it closed the connection and the batch's statements were lost. Put the `DISCONNECT` after `END BATCH`.
25
+ - **`DISCONNECT FROM <alias>`** matches the alias in any case, as `USE` does; `DISCONNECT FROM B` left a connection made `AS b` open, so a later `USE b` worked. Reconnect with `CONNECT` before using an alias you disconnected.
26
+ - **`DISCONNECT FROM` an alias that is not connected** is a metacommand error; it did nothing, so a misspelled alias left the real connection open. To disconnect only if connected, write `IF (ALIAS_DEFINED(staging)) { DISCONNECT FROM staging }`, with the alias in lowercase inside `ALIAS_DEFINED`.
27
+ - **`BREAK` in a `SCRIPT` or `INCLUDE`d file, outside a `LOOP`,** returns from that script or file, as the `BREAK` documentation says and upstream execsql did; it stopped the run. A `BREAK` in an `INCLUDE`d file inside a `LOOP` now leaves only the file, and the loop carries on; it ended the loop.
28
+ - **`BREAK` in the main script, outside any `LOOP`, `SCRIPT` or `INCLUDE`d file,** is a metacommand error: with `METACOMMAND_ERROR_HALT OFF` the script carries on and `METACOMMAND_ERROR()` is true. It stopped the run whatever that setting said.
29
+ - **A `BEGIN BATCH` block left before its `END BATCH`** by `BREAK`, an error or `HALT` is rolled back; it committed the statements run so far. To keep a batch's work and then `BREAK`, put the `BREAK` after `END BATCH`. A nested batch left by `BREAK` while the outer batch carries on is now committed or rolled back with the outer batch; it was committed at once. Under `AUTOCOMMIT OFF` your own `COMMIT` or `ROLLBACK` still decides, as before.
30
+ - **An `ON ERROR_HALT` or `ON CANCEL_HALT` script after a halt inside `BEGIN BATCH`** runs after the batch is rolled back and still commits its own SQL, such as a row it writes to a log table (unless `AUTOCOMMIT` is `OFF`).
31
+ - **`--manifest`** counts each `INCLUDE` and `EXECUTE SCRIPT` in `statements.metacommands`, including one that fails or that `IF EXISTS` skips.
32
+
33
+ ### Fixed
34
+
35
+ - **A commit that fails** (a deferred constraint checked at COMMIT) rolls back what it was committing, so none of it is stored: an SQL statement, `IMPORT`, `COPY`, `EXECUTE`, or `AUTOCOMMIT ON` committing what was held under `AUTOCOMMIT OFF`. On SQLite, when the script carried on (`ERROR_HALT OFF` for an SQL statement, `METACOMMAND_ERROR_HALT OFF` for a metacommand, or an `ON ERROR_HALT` script), the next statement's commit stored it, including the rows reported as failed.
36
+ - **SIGTERM while `SYSTEM_CMD` runs a command** stops the command just as it starts, as its `system_cmd_timeout` runs out, and under the Textual console (`--gui-framework textual`), where the script also stops at that `SYSTEM_CMD`; the command was left running after execsql exited.
37
+ - **`system_cmd_timeout` running out on a command *execsql* cannot stop** (one run as another user, through `sudo` for example) fails the `SYSTEM_CMD` at once, with `$SYSTEM_CMD_EXIT_STATUS` 124 and an error giving the command's process ID; execsql waited for the command to finish and then stopped with a permission error.
38
+ - **`END BATCH` whose commit fails on one database** rolls back the batch's databases not yet committed; a later statement on them, such as an `ON ERROR_HALT` script's, committed the failed batch's rows.
39
+ - **`BREAK` in the main script, outside any `LOOP`, `SCRIPT` or `INCLUDE`d file,** is reported on its own line; it named the statement before it.
40
+ - **`INCLUDE` and `EXECUTE SCRIPT` inside an inline `IF (…) { … }`** run again; they stopped the run with "should be handled by the AST executor".
41
+ - **`INCLUDE`, `EXECUTE SCRIPT` and an inline `IF` added with `EXTEND SCRIPT … WITH METACOMMAND`** run when the script does; they stopped the run the same way.
42
+ - **An `INCLUDE` or `EXECUTE SCRIPT` that a substitution variable supplies** (`-- !x! !!cmd!!`) says it cannot run and to write it in the script; it reported "should be handled by the AST executor".
43
+ - **`execsql lint` and the language server** check and link `INCLUDE` and `EXECUTE SCRIPT` inside an inline `IF`.
44
+ - **`execsql run --dry-run`** lists `INCLUDE` and `EXECUTE SCRIPT`.
45
+ - **`execsql lint`** checks the variables in an `INCLUDE` file name and in `EXECUTE SCRIPT` arguments and loop conditions (V001, V002), and no longer reports an `INCLUDE` inside `IF (FILE_EXISTS(file))` as a missing file (I001).
46
+ - **`INCLUDE` of a file that does not exist, `EXECUTE SCRIPT` of a script that does not exist, and `EXECUTE SCRIPT` without a required argument** are metacommand errors: with `METACOMMAND_ERROR_HALT OFF` the script carries on and `METACOMMAND_ERROR()`, `$LAST_ERROR` and `$ERROR_MESSAGE` say what failed. They stopped the run whatever that setting said.
47
+ - **Error reports name the metacommand as written** (`Metacommand: INCLUDE missing.sql`), without `-- !x!`; a failed `INCLUDE`, `EXECUTE SCRIPT`, `IF`, `ELSEIF` or `LOOP` was reported with an empty `Metacommand:` line.
48
+ - **An `IF`, `ELSEIF`, `ANDIF`, `ORIF` or `LOOP` condition that cannot be evaluated** is reported on its own line with its text (`Line 3 … Metacommand: ANDIF (NO_SUCH_FN(x))`), not as an "Uncaught exception" on another statement's line. It still stops the run.
49
+ - **`WRITE SCRIPT`** writes an `EXECUTE SCRIPT … WHILE` / `UNTIL` as written; it wrote `LOOP WHILE`, which does not read back as `EXECUTE SCRIPT`.
50
+ - **`--profile`** shows an `EXECUTE SCRIPT` or `INCLUDE` as written, with its `IF EXISTS`, arguments and `WHILE` / `UNTIL`.
51
+
52
+ ______________________________________________________________________
53
+
54
+ ## [2.36.0] - 2026-10-19
55
+
56
+ ### Changed
57
+
58
+ - **`execsql.run()` from a notebook, the REPL or `python -c`** runs `IMPORT` and `COPY` about four times as fast: reading execsql's settings there cost about 12 µs each time, now 0.1 µs (a 200,000-row column scan went from 3.5 s to 0.8 s). The `execsql` command gets a smaller gain.
59
+
60
+ ______________________________________________________________________
61
+
16
62
  ## [2.35.0] - 2026-10-18
17
63
 
18
64
  ### Added
@@ -75,7 +75,7 @@ uv run python -m tests.corpus.record my_new_case
75
75
  uv run pytest tests/corpus
76
76
  ```
77
77
 
78
- Use only syntax upstream accepts; read `_execsql/execsql.py` when unsure. A case must not open a GUI dialog (`HALT "message"`, `PROMPT`) or loop forever under upstream: both hang the recording. A difference from upstream fails the test unless `tests/corpus/changes.json` lists it with both values, a `status` (`accepted` for an upstream bug execsql2 fixed on purpose, `open` for one not yet decided) and the reason.
78
+ Use only syntax upstream accepts; read `_execsql/execsql.py` when unsure. A case must not open a GUI dialog (`HALT "message"`, `PROMPT`) or loop forever under upstream: both hang the recording. Nor may it read a file it has just written (`FILE_EXISTS`, `ZIP`, `IMPORT` right after a `WRITE`): both programs write files in the background, so the result depends on timing; put such a file among the case's inputs instead. A difference from upstream fails the test unless `tests/corpus/changes.json` lists it with both values, a `status` (`accepted` for an upstream bug execsql2 fixed on purpose, `open` for one not yet decided) and the reason.
79
79
 
80
80
  ## Building the Docs
81
81
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: execsql2
3
- Version: 2.35.0
3
+ Version: 2.37.0
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/en/stable/
6
6
  Project-URL: Repository, https://github.com/geocoug/execsql
@@ -441,7 +441,7 @@ execsql format --no-sql --in-place scripts/
441
441
  ```yaml
442
442
  repos:
443
443
  - repo: https://github.com/geocoug/execsql
444
- rev: v2.35.0
444
+ rev: v2.37.0
445
445
  hooks:
446
446
  - id: execsql-format
447
447
  - id: execsql-lint
@@ -321,7 +321,7 @@ execsql format --no-sql --in-place scripts/
321
321
  ```yaml
322
322
  repos:
323
323
  - repo: https://github.com/geocoug/execsql
324
- rev: v2.35.0
324
+ rev: v2.37.0
325
325
  hooks:
326
326
  - id: execsql-format
327
327
  - id: execsql-lint
@@ -88,25 +88,25 @@ ______________________________________________________________________
88
88
 
89
89
  New options in `execsql.conf`:
90
90
 
91
- | Option | Section | Description |
92
- | -------------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93
- | `use_keyring` | `[connect]` | Use the OS keyring for credential storage (default: `yes`). |
94
- | `trust_server_certificate` | `[connect]` | SQL Server: accept a self-signed server certificate (ODBC Driver 18 verifies it by default); also `?trust_server_certificate=yes` on an `mssql://` URL. Default: `no`. |
95
- | `exact_decimals` | `[input]` | Give a column of decimals with different numbers of places an exact `DECIMAL(p,s)` type instead of a float (default: `no`); also `CONFIG EXACT_DECIMALS`. |
96
- | `show_progress` | `[input]` | Enable Rich progress bar for IMPORT (default: `no`). |
97
- | `import_progress_interval` | `[input]` | Log a status line every N rows during IMPORT (default: `0`). |
98
- | `gui_framework` | `[interface]` | GUI backend: `tkinter` (default) or `textual` (terminal UI). |
99
- | `log_sql` | `[config]` | Enable SQL audit logging (default: `no`). |
100
- | `max_log_size_mb` | `[config]` | Rotate the log file at this size in MB (default: `0` = disabled). |
101
- | `macos_config_file` | `[config]` | Additional config file path, active only on macOS. |
102
- | `allow_rm_file` | `[config]` | Disable the `RM_FILE` metacommand (default: `yes`). Symmetric with `allow_system_cmd`; also `--no-rm-file` on the CLI. |
103
- | `allow_serve` | `[config]` | Disable the `SERVE` metacommand (default: `yes`). Symmetric with `allow_system_cmd`; also `--no-serve` on the CLI. |
104
- | `include_root` | `[config]` | Path-containment root for `INCLUDE` / `EXECUTE SCRIPT` (default: none). When set, attempts to include files outside this root via `../`, absolute paths, drive letters, or UNC paths are rejected with an error. |
105
- | `serve_root` | `[config]` | Path-containment root for `SERVE` (default: none). Same semantics as `include_root`. |
106
- | `template_root` | `[config]` | Path-containment root for Jinja2 / `string.Template` loaders (default: none). Same semantics as `include_root`. |
107
- | `max_substitution_bytes` | `[config]` | Byte ceiling on a single substitution-variable expansion (default: `10485760` = 10 MB) to defeat exponential-expansion bombs. |
108
- | `indent`, `leading_comma`, `sql` | `[format]` | Layout defaults for `execsql format`; a flag on the command line wins. |
109
- | `select`, `ignore`, `strict` | `[lint]` | Rule selection and strictness for `execsql lint`; `--select` / `--ignore` replace the lists, `--strict` / `--no-strict` override `strict`. |
91
+ | Option | Section | Description |
92
+ | -------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
93
+ | `use_keyring` | `[connect]` | Use the OS keyring for credential storage (default: `yes`). |
94
+ | `trust_server_certificate` | `[connect]` | SQL Server: accept a self-signed server certificate (ODBC Driver 18 verifies it by default); also `?trust_server_certificate=yes` on an `mssql://` URL. Default: `no`. |
95
+ | `exact_decimals` | `[input]` | Give a column of decimals with different numbers of places an exact `DECIMAL(p,s)` type instead of a float (default: `no`); also `CONFIG EXACT_DECIMALS`. |
96
+ | `show_progress` | `[input]` | Enable Rich progress bar for IMPORT (default: `no`). |
97
+ | `import_progress_interval` | `[input]` | Log a status line every N rows during IMPORT (default: `0`). |
98
+ | `gui_framework` | `[interface]` | GUI backend: `tkinter` (default) or `textual` (terminal UI). |
99
+ | `log_sql` | `[config]` | Enable SQL audit logging (default: `no`). |
100
+ | `max_log_size_mb` | `[config]` | Rotate the log file at this size in MB (default: `0` = disabled). |
101
+ | `macos_config_file` | `[config]` | Additional config file path, active only on macOS. |
102
+ | `allow_rm_file` | `[config]` | Disable the `RM_FILE` metacommand (default: `yes`). Symmetric with `allow_system_cmd`; also `--no-rm-file` on the CLI. |
103
+ | `allow_serve` | `[config]` | Disable the `SERVE` metacommand (default: `yes`). Symmetric with `allow_system_cmd`; also `--no-serve` on the CLI. |
104
+ | `include_root` | `[config]` | Path-containment root for `INCLUDE` files (default: none). When set, attempts to include files outside this root via `../`, absolute paths, drive letters, or UNC paths are rejected with an error that stops the run, even with `METACOMMAND_ERROR_HALT OFF`. |
105
+ | `serve_root` | `[config]` | Path-containment root for `SERVE` (default: none). The same containment checks as `include_root`; a refused path is an ordinary metacommand error. |
106
+ | `template_root` | `[config]` | Path-containment root for Jinja2 / `string.Template` loaders (default: none). The same containment checks as `include_root`; a refused path is an ordinary metacommand error. |
107
+ | `max_substitution_bytes` | `[config]` | Byte ceiling on a single substitution-variable expansion (default: `10485760` = 10 MB) to defeat exponential-expansion bombs. |
108
+ | `indent`, `leading_comma`, `sql` | `[format]` | Layout defaults for `execsql format`; a flag on the command line wins. |
109
+ | `select`, `ignore`, `strict` | `[lint]` | Rule selection and strictness for `execsql lint`; `--select` / `--ignore` replace the lists, `--strict` / `--no-strict` override `strict`. |
110
110
 
111
111
  ### Tools
112
112
 
@@ -190,7 +190,7 @@ Formatter correctness notes added in the 2.19.x line:
190
190
 
191
191
  ### Debugging { #debugging }
192
192
 
193
- execsql2 adds an interactive debug REPL (no upstream equivalent), triggered either by the `BREAKPOINT` metacommand or the `--debug` CLI flag (step-through mode). The REPL prompts with `execsql debug>`, and input runs as if it were the next lines of the script where it paused, so SQL (ending with `;`, results shown as tables), metacommands and blocks all work, in the paused script's variable scope and transaction. A `SUB` typed there is still set when the script resumes, a `BREAK` inside a loop leaves the loop, and `HALT` ends the run. An error ends only the input that caused it, without running `ON ERROR_HALT` actions. Input starting with `.` is a REPL command (`.continue`, `.quit`, `.next`, `.vars`, `.vars VAR`, `.where`, `.stack`, `.set`, `.scripts`, `.cancel`, `.help`). `BREAKPOINT` is silently skipped when stdin is not a TTY so it does not hang CI. Full command list and behavior: [Debugging guide](../guides/debugging.md).
193
+ execsql2 adds an interactive debug REPL (no upstream equivalent), triggered either by the `BREAKPOINT` metacommand or the `--debug` CLI flag (step-through mode). The REPL prompts with `execsql debug>`, and input runs as if it were the next lines of the script where it paused, so SQL (ending with `;`, results shown as tables), metacommands and blocks all work, in the paused script's variable scope and transaction. A `SUB` typed there is still set when the script resumes, a `BREAK` leaves the `LOOP`, `SCRIPT` or included file the script paused in, and `HALT` ends the run. An error ends only the input that caused it, without running `ON ERROR_HALT` actions. Input starting with `.` is a REPL command (`.continue`, `.quit`, `.next`, `.vars`, `.vars VAR`, `.where`, `.stack`, `.set`, `.scripts`, `.cancel`, `.help`). `BREAKPOINT` is silently skipped when stdin is not a TTY so it does not hang CI. Full command list and behavior: [Debugging guide](../guides/debugging.md).
194
194
 
195
195
  ### Library API
196
196
 
@@ -291,7 +291,12 @@ The legacy flat command-list engine (`_parse_script_lines` / `runscripts` / `Com
291
291
  - **Native INCLUDE handling** — The AST executor parses INCLUDE'd files with the AST parser and executes them through the tree-walking executor. Control flow structures (IF/LOOP/BATCH/SCRIPT) in included files are fully tree-driven, with correct deferred variable handling and source-span error reporting.
292
292
  - **Circular INCLUDE detection** — The executor tracks the full include chain and detects circular references (e.g. A includes B includes A), reporting the full chain in the error message. Upstream has no such detection.
293
293
  - **LOOP conditions are read on every pass** — The variables in a `LOOP WHILE` / `LOOP UNTIL` condition are substituted afresh before each pass, so `LOOP WHILE (IS_GT(10, !!n!!))` with `SUB_ADD n 1` in the body stops when `n` reaches 10. Upstream substituted them once, when the `LOOP` line ran, so a condition on a variable already defined never changed: the loop ran until a `BREAK`, or forever. Upstream scripts got per-pass conditions only from variables not yet defined when the loop started ("phantom variables") or from deferred `!{var}!` references, and both still work.
294
- - **BREAK outside LOOP is an error** — `BREAK` outside a loop block now raises an error (exit 1) instead of being silently ignored. This catches script bugs that upstream would not report.
294
+ - **Control flow from a substitution variable** — A metacommand line whose text a substitution variable supplies (`-- !x! !!cmd!!`) cannot be an `INCLUDE`, `EXECUTE SCRIPT` (or `EXEC SCRIPT` / `RUN SCRIPT`) or a block metacommand (`IF`, `ELSEIF`, `ANDIF`, `ORIF`, `ELSE`, `ENDIF`, `LOOP`, `END LOOP`, `BEGIN BATCH`, `END BATCH`, `BEGIN SCRIPT` (or `CREATE SCRIPT`), `END SCRIPT`, `BEGIN SQL`, `END SQL`). execsql2 decides which lines are includes and blocks when it parses the script, before any variable is substituted, so such a line does not run. Most of these are a metacommand error, which `METACOMMAND_ERROR_HALT OFF` skips without printing anything (test for it with `METACOMMAND_ERROR()`; `execsql.run()` still lists it in `result.errors`); `END LOOP`, `BEGIN` / `CREATE` / `END SCRIPT` and `BEGIN` / `END SQL` stop the run whatever that setting says. Upstream substituted the line first and ran it. Write the metacommand in the script and put the variable in its argument instead: `INCLUDE !!file!!`, `EXECUTE SCRIPT !!name!!` and `IF (!!condition!!)` all work (decided in #113).
295
+ - **BREAK leaves the innermost LOOP, SCRIPT or included file** — As upstream documents and did: a `BREAK` in a `SCRIPT` or `INCLUDE`d file outside a `LOOP` returns from that script or file, and never ends a loop that called the script or included the file. Two differences remain. A `BREAK` in the main script, outside all of these, is a metacommand error reported on the `BREAK`'s own line (the run stops unless `METACOMMAND_ERROR_HALT` is `OFF`); upstream logged a warning and carried on, so a misplaced `BREAK` went unnoticed. And a `BREAK` that is the body of an inline `IF (…) { BREAK }` leaves the loop; upstream ignored it and the loop ran on (decided in #115).
296
+ - **A batch left before END BATCH is rolled back** — A `BREAK`, an error or a `HALT` inside `BEGIN BATCH` rolls the batch back, and the script's later statements are committed as usual. Upstream left the batch open after a `BREAK`, so nothing after it was committed either and the run ended by rolling it all back. An error or `HALT` rolled the batch back in both, but upstream ran the `ON ERROR_HALT` / `ON CANCEL_HALT` script inside the still-open batch and so lost what that script wrote; execsql2 rolls back first, and the script's SQL is committed (unless `AUTOCOMMIT` is `OFF`). A nested batch that a `BREAK` leaves while the batch around it carries on is not rolled back on its own: the outer batch commits or rolls back its statements, so the result matches upstream there. Under `AUTOCOMMIT OFF`, leaving a batch early rolls nothing back, as `END BATCH` commits nothing. execsql2 2.36.0 and earlier committed the half-finished batch on a `BREAK`, an error or `HALT`, and committed a nested batch left by `BREAK` at once instead of with the outer batch (#121).
297
+ - **END BATCH whose commit fails** — When a commit at `END BATCH` fails on one database (a deferred constraint, for example), execsql2 rolls back that database and the batch's databases not yet committed, then reports an SQL error on the `END BATCH` line, which `ERROR_HALT` governs. An enclosing batch then rolls back at its own `END BATCH` instead of committing, and no batch opened inside it afterwards commits either (`ROLLBACK BATCH` does not undo this; `IMPORT`, `COPY`, `EXECUTE` and `AUTOCOMMIT ON WITH COMMIT` still commit unless `AUTOCOMMIT` is `OFF`, as in any batch). A database under `AUTOCOMMIT OFF` is left to the script. `END BATCH` clears `SQL_ERROR()` before its commit, as an SQL statement does, so right after `END BATCH` it says whether the batch was committed; upstream kept the value left by the last statement run before it. Upstream left the uncommitted databases' statements pending, so the next statement that committed on them (an `ON ERROR_HALT` script's, say) committed part of the failed batch; it reported the failure as a metacommand error. execsql2 2.36.0 and earlier did the same and reported it as an uncaught exception on a line of execsql's source (#125).
298
+ - **A failed commit is rolled back** — When a commit fails (a deferred foreign key, for example), execsql2 rolls the transaction back before it reports the error, so nothing it was committing is stored: an SQL statement, `IMPORT`, `COPY`, `EXECUTE`, or the commit of what was held under `AUTOCOMMIT OFF` (`AUTOCOMMIT ON WITH COMMIT`, or the next statement after a plain `AUTOCOMMIT ON`). Upstream left the transaction open where the DBMS does (SQLite), and when the script carried on (`ERROR_HALT OFF` for an SQL statement, `METACOMMAND_ERROR_HALT OFF` for a metacommand, or an `ON ERROR_HALT` script), the next statement that committed stored what it had reported as failed (#135).
299
+ - **Anything that fails inside a batch** — An SQL statement, a metacommand, or SQL a metacommand runs (`EXECUTE`, `EXPORT QUERY`, `SUBDATA`, `SELECT_SUB`, `IMPORT`, …) that fails inside `BEGIN BATCH` keeps the batch, and every batch around it, from being committed: `END BATCH` rolls back what the batch ran after the failure and reports an SQL error ("The batch was not committed: an error on line …."), so `SQL_ERROR()` right after `END BATCH` is true. The script reaches `END BATCH` only with `ERROR_HALT OFF` (for an SQL error) or `METACOMMAND_ERROR_HALT OFF` (for a metacommand error); if `ERROR_HALT` is `ON` at `END BATCH`, the run stops there, where upstream committed and carried on. A failed statement had already rolled back the batch's earlier statements on its database, in upstream too. Upstream committed the statements after the failure at `END BATCH`, a partial batch, and `SQL_ERROR()` was false if the last one succeeded. `ROLLBACK BATCH` does not undo the failure. Under `AUTOCOMMIT OFF` the script's own transaction is left to it (#125).
295
300
  - **File writer is a thread, one per run** — `WRITE`, `TEE` and the other text-file metacommands hand their output to a background thread owned by the run's `RuntimeContext`, which `execsql.run()` stops before returning. Upstream uses one `multiprocessing` subprocess for the whole program; under the `spawn` start method (macOS, Windows) that re-imported the calling program, so a library caller without an `if __name__ == "__main__":` guard ran its script twice.
296
301
  - **Instance-scoped script registry** — Named SCRIPT blocks are stored on the `RuntimeContext` instance instead of a module-level dict, preventing cross-execution contamination.
297
302
 
@@ -302,6 +307,7 @@ The legacy flat command-list engine (`_parse_script_lines` / `runscripts` / `Com
302
307
  - **Database and driver error messages** — End with the error itself (`OperationalError: table t already exists`). Upstream appended "in <file> on line N of execsql", a line of its own source; in the package the file was often a driver's and the line number another file's. Where in execsql the error was raised goes to `execsql.log` as `Raised at: execsql/<module>.py:<line>`.
303
308
  - **Missing optional package messages** — Name the execsql2 extra that installs the package and how to add it to a `uv tool` or `pipx` install without dropping the extras already there (`uv tool install "execsql2[...,postgres]"`). Upstream pointed at the package's web page.
304
309
  - **Config file errors** — An invalid value in `execsql.conf` stops a run with `Configuration error: <file>: <problem>` (and the line, for an unreadable file) plus a pointer to `execsql config --validate`. Upstream printed `Configuration error on line N of execsql.py`, where N was a line of its own source. A duplicate key, a missing section header or a bare `%` is reported the same way; upstream failed with an uncaught exception. Errors raised by `ConfigData` for a file are `ConfigFileError`, a subclass of `ConfigError`.
310
+ - **A condition that cannot be evaluated stops the run** — An `IF`, `ELSEIF`, `ANDIF`, `ORIF`, `LOOP` or `EXECUTE SCRIPT … WHILE` / `UNTIL` condition that cannot be evaluated stops the run, even with `METACOMMAND_ERROR_HALT OFF` and `ERROR_HALT OFF`, and the error report names the line and the condition. That covers an unknown test or malformed condition (`IF (NO_SUCH_FN(x))`) and a test that fails in the database (`HASROWS(no_such_table)`). Upstream carried on: it skipped a bad inline `IF (…) { … }` as a metacommand error, hiding a failed query along with a typo; a top-level block `IF` ran both its body and its `ELSE` branch, and one inside another `IF` ran its body, skipped its `ELSE`, and closed the enclosing `IF` early, so that `IF`'s `ELSE` branch ran too. Upstream also stopped on a bad `LOOP` or `EXECUTE SCRIPT … WHILE` condition, but reported a line inside the loop. A condition that cannot be evaluated is a script bug, and carrying on would run the script down a branch nobody chose (decided in #112).
305
311
  - **ASSERT error type** — `ASSERT` failures now use a dedicated `"assert"` error type that produces `**** Assertion failed.` instead of `**** Error in metacommand.`. This distinguishes intentional script-level checks from actual metacommand errors. Upstream did not have `ASSERT`.
306
312
 
307
313
  ______________________________________________________________________
@@ -440,6 +446,10 @@ These are behavioral changes driven by security or correctness issues in the ups
440
446
  | LaTeX export escaped only the underscore | Cells were written as `str(c).replace("_", r"\_")`, leaving every other LaTeX special raw. `&` is the column separator this exporter itself emits, so an ampersand in a value added a column and the `.tex` no longer compiled; `%` commented out the rest of the row. All of `\ & % $ # _ { } ~ ^` are now escaped, in both the header and the body. |
441
447
  | `ON ERROR_HALT WRITE … TO` a file wrote nothing | Upstream passed the `(text, flag)` pair that variable substitution returns on as the text, so writing the message failed after the file was opened and the file stayed empty. The message is written. |
442
448
  | Mixed-scale decimals keep every digit | `IMPORT` / `COPY … TO NEW` gave a column of decimals with different numbers of places (`1.50`, `2`, `-3.25`) a floating-point type, which also held values a double cannot store exactly: `1234567890.1234567891` was stored as `1234567890.1234567`. Such a column is still a float, unless a value has more than 15 significant digits; then it is `DECIMAL(p,s)`. The `exact_decimals` setting makes every such column exact. |
449
+ | XML export wrote NULL as the literal "None" | `str()` was applied to every value, so a NULL appeared in the XML as the text None. It is now an empty element. |
450
+ | `WRITE SCRIPT` output | The `BEGIN SCRIPT` and `END SCRIPT` lines were written without `-- !x!`, so a script that `INCLUDE`d the file ran them as SQL. They are written as metacommands. |
451
+ | Line break inside a quoted value | Delimiter detection read the file line by line, so a quoted value with a line break in it made every line look different and no delimiter was found: the whole file became one column named after the header line (`id,note`). The file is read as CSV, so the line break stays inside the value. |
452
+ | `EXPORT` after `CD` | `EXPORT` failed after `CD` with `No such file or directory: …/<new dir>/script.sql`, looking for the script in the new directory. The output file is written relative to the current directory. |
443
453
  | LaTeX export wrote NULL as the literal "None" | `str(c)` was applied to every value including `None`, so a NULL appeared in the typeset table as the word None. It is now an empty cell, matching every other exporter. |
444
454
  | HTML export rendered zero as an empty cell | Cells were written as `html.escape(str(v)) if v else ''`. `0`, `False`, and `""` are all falsy, so a zero measurement rendered exactly like a NULL and the two could not be told apart in the output. The test is now `if v is not None`. Both `export_html` and `export_cgi_html` were affected. |
445
455
  | Markdown export broke the table on an embedded newline | `_cell()` escaped pipes but not newlines, and a GFM table row is a single line: a value containing one ended the row mid-cell and left the rest of that row's values on a stray line outside the table entirely. Newlines are now written as `<br>`, which is how GFM expresses a line break inside a cell. |
@@ -451,6 +461,7 @@ These are behavioral changes driven by security or correctness issues in the ups
451
461
  | Values loaded into an existing table | `IMPORT` and `COPY` converted every value to the type guessed from the source data, even when the table was already there with its own column types, so a text column got a different string than the source held (`yes` and `1` stored as `true`, `01/05/2024` as `2024-01-05 00:00:00`, `1e3` as `1000`), and on PostgreSQL a column of 0s and 1s copied into an integer column failed (the guess was boolean). For a table that exists, the target column's type now decides: a text column gets the value as written, a number column gets true/false values as 1 and 0, and other columns are converted as before. Each adapter reads the column types from its catalog (`pg_attribute`, `SHOW COLUMNS`, `sys.columns`) or its driver's description of the table. `TO NEW` / `REPLACEMENT` are unchanged. |
452
462
  | Missing dates loaded into MySQL | `IMPORT` and `COPY` sent a missing value in a column scanned as a date or timestamp as `''`, so MySQL stored `0000-00-00` (or `0` in a number column) instead of NULL. It is sent as NULL. |
453
463
  | Fractions loaded into an integer column | A value with a fraction going into an integer column (including `DECIMAL(p,0)`, `NUMERIC(p)` and Oracle `NUMBER(p)`) of an existing table is an error naming the value and the column. Upstream sent the number and the database rounded it (`1.5` → `2`; SQL Server truncated it to `1`). |
464
+ | `DISCONNECT` | Refuses a database that an open `BEGIN BATCH` has used, as documented; upstream's check compared the alias to connection objects and never fired, so the connection closed and the batch's statements were lost. The refusal is an error inside the batch, so `END BATCH` does not commit it. The alias matches in any case, as `USE` does (upstream's `DISCONNECT FROM B` left a connection made `AS b` open), and an alias that is not connected is a metacommand error (upstream ignored it) (#124). |
454
465
 
455
466
  ______________________________________________________________________
456
467
 
@@ -61,18 +61,18 @@ execsql debug>
61
61
 
62
62
  Because input runs inside the paused script, it changes what the script sees after `.continue`:
63
63
 
64
- | You type at the breakpoint | Effect on the script |
65
- | --------------------------------- | ------------------------------------------------------------------------------------- |
66
- | `!x! SUB threshold 50` | `!!threshold!!` is 50 for the rest of the run |
67
- | `select '!!~counter!!';` | Reads the paused SCRIPT's `~local` and `#param` variables |
68
- | `insert into staging values (1);` | Committed as the script's own SQL would be: now, unless `AUTOCOMMIT OFF` or a batch |
69
- | `!x! USE other_db` | The script continues against `other_db` |
70
- | `!x! BREAK` | Inside a `LOOP` (or a looping `EXECUTE SCRIPT`), leaves that loop, as a `BREAK` would |
71
- | `!x! HALT` | Ends the run |
64
+ | You type at the breakpoint | Effect on the script |
65
+ | --------------------------------- | --------------------------------------------------------------------------------------- |
66
+ | `!x! SUB threshold 50` | `!!threshold!!` is 50 for the rest of the run |
67
+ | `select '!!~counter!!';` | Reads the paused SCRIPT's `~local` and `#param` variables |
68
+ | `insert into staging values (1);` | Committed as the script's own SQL would be: now, unless `AUTOCOMMIT OFF` or a batch |
69
+ | `!x! USE other_db` | The script continues against `other_db` |
70
+ | `!x! BREAK` | Leaves the `LOOP`, `SCRIPT` or `INCLUDE`d file the script paused in, as a `BREAK` would |
71
+ | `!x! HALT` | Ends the run |
72
72
 
73
73
  **Errors end only the input that caused them.** A SQL or metacommand error that would halt the script is printed, and the prompt reads the next input; `ON ERROR_HALT` actions do not run. `HALT` and `.quit` still end the run.
74
74
 
75
- **Transactions follow the script's rules.** Each SQL statement is committed as it runs unless `AUTOCOMMIT OFF` is in effect or the breakpoint is inside `BEGIN BATCH`. The prompt then reads `execsql debug*>`, so you can see that what you type is not committed yet.
75
+ **Transactions follow the script's rules.** Each SQL statement is committed as it runs unless `AUTOCOMMIT OFF` is in effect or the breakpoint is inside `BEGIN BATCH`. The prompt then reads `execsql debug*>`, so you can see that what you type is not committed yet. Inside `BEGIN BATCH`, a statement or metacommand you type that fails keeps the batch from being committed, as one in the script does: `END BATCH` rolls it back and reports an error.
76
76
 
77
77
  **Commands to the REPL** start with `.`:
78
78
 
@@ -272,7 +272,7 @@ select id,name,created_at from users where active = true order by name;
272
272
  ```yaml
273
273
  repos:
274
274
  - repo: https://github.com/geocoug/execsql
275
- rev: v2.35.0
275
+ rev: v2.37.0
276
276
  hooks:
277
277
  - id: execsql-format
278
278
  - id: execsql-lint # optional: fail the commit on lint errors
@@ -376,7 +376,7 @@ The section and property names that may be used in a configuration file are list
376
376
  : When set to "No", the `SYSTEM_CMD` (SHELL) metacommand is disabled. Any script that attempts to execute an OS command will fail with an error. The default is "Yes". This can also be set via the `--no-system-cmd` CLI flag or `allow_system_cmd=False` in the library API. See [Security — Disabling SYSTEM_CMD](security.md#disable_system_cmd) for details.
377
377
 
378
378
  `system_cmd_timeout` { #system_cmd_timeout }
379
- : Maximum number of seconds a foreground `SYSTEM_CMD` may run before *execsql* stops it. The default is `0`, which means no timeout. When a foreground command times out, `$SYSTEM_CMD_EXIT_STATUS` is set to `124` and the metacommand fails. `SYSTEM_CMD ... CONTINUE` starts a detached background process and is not timeout-managed by this setting.
379
+ : Maximum number of seconds a foreground `SYSTEM_CMD` may run before *execsql* stops it. The default is `0`, which means no timeout. When a foreground command times out, `$SYSTEM_CMD_EXIT_STATUS` is set to `124` and the metacommand fails. If the operating system will not let *execsql* stop the command (it runs as another user, through `sudo` for example), the error says so and gives its process ID. `SYSTEM_CMD ... CONTINUE` starts a detached background process and is not timeout-managed by this setting.
380
380
 
381
381
  `allow_rm_file` { #allow_rm_file }
382
382
  : When set to "No", the `RM_FILE` metacommand (which deletes a file) is disabled. Any script that attempts to remove a file will fail with an error. The default is "Yes". This can also be set via the `--no-rm-file` CLI flag or `allow_rm_file=False` in the library API. Symmetric with `allow_system_cmd`.
@@ -385,13 +385,13 @@ The section and property names that may be used in a configuration file are list
385
385
  : When set to "No", the [`SERVE`](metacommands.md#serve) metacommand (which copies a file to stdout with Content-Type and Content-Disposition headers, for use as a CGI script) is disabled. The default is "Yes". This can also be set via the `--no-serve` CLI flag or `allow_serve=False` in the library API. Symmetric with `allow_system_cmd`.
386
386
 
387
387
  `include_root` { #include_root }
388
- : Root directory under which `INCLUDE` and `EXECUTE SCRIPT` targets must resolve. When set, attempts to include files outside this root via `../`, absolute paths, drive letters, or UNC paths are rejected with an error. Default: no containment (any readable path is permitted). See [Security — Path containment roots](security.md#path-containment-roots) for the full per-handler matrix.
388
+ : Root directory under which the files `INCLUDE` reads must resolve (`EXECUTE SCRIPT` runs a `SCRIPT` block, not a file). When set, attempts to include files outside this root via `../`, absolute paths, drive letters, or UNC paths are rejected with an error that stops the run, even with `METACOMMAND_ERROR_HALT OFF`. Default: no containment (any readable path is permitted). See [Security — Path containment roots](security.md#path-containment-roots) for the full per-handler matrix.
389
389
 
390
390
  `serve_root` { #serve_root }
391
- : Root directory under which `SERVE` targets must resolve. Same containment semantics as `include_root` — paths that escape via `../` or absolute references are rejected. Default: no containment.
391
+ : Root directory under which `SERVE` targets must resolve. The same containment checks as `include_root`, but a refused path is an ordinary metacommand error — paths that escape via `../` or absolute references are rejected. Default: no containment.
392
392
 
393
393
  `template_root` { #template_root }
394
- : Root directory under which Jinja2 / `string.Template` loader paths must resolve. Same containment semantics as `include_root`. Default: no containment.
394
+ : Root directory under which Jinja2 / `string.Template` loader paths must resolve. The same containment checks as `include_root`, but a refused path is an ordinary metacommand error. Default: no containment.
395
395
 
396
396
  `max_substitution_bytes` { #max_substitution_bytes }
397
397
  : Maximum byte size of any single substitution-variable expansion, enforced by the `substitute_vars()` engine to defeat exponential-expansion bombs (a script that nests `!!a!!` referring to `!!b!!` referring to `!!a!!` and so on can otherwise blow past memory). When set to a positive integer, expansions exceeding the threshold raise an error. Default: `10485760` (10 MB).
@@ -158,7 +158,7 @@ The `execsql-lint` [pre-commit](https://pre-commit.com/) hook runs `execsql lint
158
158
  ```yaml
159
159
  repos:
160
160
  - repo: https://github.com/geocoug/execsql
161
- rev: v2.35.0
161
+ rev: v2.37.0
162
162
  hooks:
163
163
  - id: execsql-lint
164
164
  args: [--ignore, V002] # optional: any execsql lint option
@@ -340,6 +340,14 @@ An `INCLUDE` names a file that does not exist. Lint resolves a relative path aga
340
340
 
341
341
  Not reported for `INCLUDE IF EXISTS`, or when the path contains a `!!variable!!`, since the file then depends on values known only at run time.
342
342
 
343
+ Not reported either inside an `IF` that runs only when the file exists, block or inline:
344
+
345
+ ```sql
346
+ -- !x! IF (FILE_EXISTS(local_settings.sql)) { INCLUDE local_settings.sql }
347
+ ```
348
+
349
+ An `ANDIF (FILE_EXISTS(…))` guards its file too; an `ORIF` lets the branch run without the file, so its `IF` guards nothing.
350
+
343
351
  Also reported, as "INCLUDE path cannot be checked", for a name the operating system rejects outright (longer than it allows, for example). The other scripts in the same `execsql lint` run are still checked; a script lint cannot check at all is reported as one P001 error naming it.
344
352
 
345
353
  ### I002 `missing-script` { #i002 }
@@ -110,6 +110,8 @@ If AUTOCOMMIT is set to ON without using the WITH clause, the next SQL statement
110
110
 
111
111
  If the WITH ROLLBACK clause is used when AUTOCOMMIT is turned back on, all SQL statements issued since AUTOCOMMIT was turned OFF will be rolled back.
112
112
 
113
+ If that commit fails (for example, on a deferred foreign key that is checked at COMMIT), everything issued since AUTOCOMMIT was turned OFF is rolled back, together with whatever made the commit, so none of it is stored by a later commit. The failure is reported as the error of whatever made the commit: the AUTOCOMMIT ON WITH COMMIT metacommand itself or, without the WITH clause, the next statement or metacommand that commits (or END BATCH, inside a [BATCH](#batch)). [ERROR_HALT](#error_halt) governs an SQL statement's error and [METACOMMAND_ERROR_HALT](#metacommanderrorhalt) a metacommand's.
114
+
113
115
 
114
116
  SQL statements that were issued while AUTOCOMMIT is OFF can also be committed using a SQL "COMMIT;" statement. This approach should be avoided with SQL Server, however, because *execsql* connects with SQL Server using ODBC, and Microsoft warns that SQL statements to manage transactions should not be used ["because this can cause indeterminate behavior in the driver"](https://docs.microsoft.com/en-us/sql/relational-databases/native-client/odbc/performing-transactions-in-odbc?view=sql-server-2017). For example, two "COMMIT;" statements may be needed the first time that SQL statements are committed this way.
115
117
 
@@ -211,7 +213,16 @@ Metacommands may be included inside a batch, but note that the [IMPORT](#import)
211
213
 
212
214
  What a batch can hold back depends on the DBMS; see the table under [AUTOCOMMIT](#autocommit). MySQL and Oracle commit DDL inside a batch at once, with everything before it, and *execsql* warns when that happens.
213
215
 
214
- When the END BATCH metacommand is processed by *execsql*, a commit command is sent to all databases that have been used inside the batch. Multiple databases may be used inside a batch if the [USE](#use) metacommand is used inside the batch. The BATCH metacommands therefore provide a limited sort of cross-database transaction control — note, however, that the commit statements are issued sequentially, and if a later commit statement fails, this will not roll back changes to databases for which the commit has already succeeded.
216
+ When the END BATCH metacommand is processed by *execsql*, a commit command is sent to all databases that have been used inside the batch. Multiple databases may be used inside a batch if the [USE](#use) metacommand is used inside the batch. The BATCH metacommands therefore provide a limited sort of cross-database transaction control — note, however, that the commit statements are issued sequentially, and if a later commit statement fails, this will not roll back changes to databases for which the commit has already succeeded. When a commit fails (for example, on a deferred foreign key that is checked at COMMIT), that database and the batch's databases not yet committed are rolled back, so nothing else of the batch is left for a later statement to commit; a database under [AUTOCOMMIT](#autocommit) OFF is left to the script's own COMMIT or ROLLBACK. The failure is an SQL error on the END BATCH line, reported with `Metacommand: END BATCH`: [ERROR_HALT](#error_halt), not METACOMMAND_ERROR_HALT, decides whether it halts the script. With ERROR_HALT OFF, the script carries on, and `$LAST_ERROR` is `END BATCH`. Like an SQL statement, END BATCH clears `SQL_ERROR()` before its commit and sets it if the commit fails, so test it right after END BATCH:
217
+
218
+ ```sql
219
+ -- !x! END BATCH
220
+ -- !x! IF (SQL_ERROR()) { WRITE "The batch was not committed." }
221
+ ```
222
+
223
+ Anything that fails inside a batch has the same result: an SQL statement, a metacommand, or SQL that a metacommand runs (EXECUTE, EXPORT QUERY, SUBDATA, SELECT_SUB, IMPORT and the like). If anything in a batch fails, the batch is not committed. A failed SQL statement has already rolled back its connection, taking the batch's earlier statements on it with it, and a metacommand's SQL may have done the same. END BATCH rolls back what the batch ran after the failure and reports an SQL error, "The batch was not committed: an error on line ….", which the test above catches. The script reaches END BATCH only if the error did not stop it: ERROR_HALT OFF for an SQL error, METACOMMAND_ERROR_HALT OFF for a metacommand error. If ERROR_HALT is ON at END BATCH (the default), the run stops there. Put a statement or metacommand that may fail, and that the script handles, outside the batch. Under AUTOCOMMIT OFF, END BATCH still reports the error, but the script's own transaction is left to its COMMIT or ROLLBACK. On a connection whose driver commits every statement (an ODBC DSN without transactions), the batch's statements were committed as they ran, whatever END BATCH reports.
224
+
225
+ If the failing batch is nested in another, or the failure is in a nested batch, the rollback can take the enclosing batch's earlier statements with it, so the enclosing batch is rolled back at its own END BATCH instead of committing, with an error of its own ("The batch was not committed: …", naming the failure). Once anything in a batch has failed, no END BATCH in that stack of batches commits: a batch opened inside the enclosing batch afterwards is not committed either, and ROLLBACK BATCH does not undo the failure. IMPORT, COPY, EXECUTE and AUTOCOMMIT ON WITH COMMIT, which commit on their own, still do unless AUTOCOMMIT is OFF, as they do in any batch. Statements after the outermost END BATCH run and commit as usual.
215
226
 
216
227
  The BEGIN/END BATCH metacommands can be nested. However, the inner END BATCH metacommand will ordinarily commit all changes to the databases that have been used, which may include databases used in the outer batch as well. (This behavior may be DBMS-specific, and also depend on whether any additional explicit transaction control is being used.) Therefore completion of a nested batch may result in premature commitment of some or all SQL statements in the outer batch. Similarly, a ROLLBACK BATCH metacommand within the inner batch will also roll back any SQL commands sent to the same databases in the outer batch. Thus, although the BATCH commands can be nested, database transactions may not be, depending on the DBMS in use. Nesting of BATCH metacommands allows a script file or a [SCRIPT](#beginscript) containing a batch to be [INCLUDEEd](#include) or [EXECUTEEd](#executescript), respectively, within another batch.
217
228
 
@@ -226,7 +237,23 @@ Alternatives to using batches to control the execution time of SQL statements ar
226
237
 
227
238
  The END BATCH metacommand is analogous to the "GO" command of the T-SQL language used with SQL Server utilities such as *sqlcmd*. There is no explicit equivalent to BEGIN BATCH in *sqlcmd* or other SQL Server utilities. In *sqlcmd* a new batch is automatically begun at the beginning of the script or immediately after a GO statement. execsql only starts a new batch when a BEGIN BATCH statement is encountered.
228
239
 
229
- If the end of the script file is encountered while a batch of statements is being compiled, but there is no END BATCH metacommand, the SQL statements in that incomplete batch will not be committed.
240
+ A batch is committed when it reaches END BATCH, unless something in it failed (see below). A batch left any other way is rolled back: a [BREAK](#break) out of a LOOP, SCRIPT or included file the batch is in, a [HALT](#halt), or an error that stops the run. The rollback cannot undo what was already committed inside the batch: by an IMPORT or COPY, by a nested batch's END BATCH, or by the DBMS itself, as MySQL and Oracle do for DDL (see above). Like ROLLBACK BATCH, it rolls back the connection's whole transaction, so statements held from before the batch under AUTOCOMMIT OFF, and not committed when AUTOCOMMIT was turned back ON, are rolled back with it. A nested batch left this way, while the batch around it carries on, is not rolled back on its own: its statements stay with the outer batch, which commits them at its END BATCH or rolls them back if it is left early too. With [AUTOCOMMIT](#autocommit) OFF, END BATCH commits nothing, and leaving a batch early rolls nothing back; the script's own COMMIT or ROLLBACK decides. A BEGIN BATCH with no END BATCH is an error before the script runs. To keep a batch's work and then leave a loop, end the batch first:
241
+
242
+ ```sql
243
+ create table passes (n integer);
244
+ -- !x! SUB n 0
245
+ -- !x! LOOP WHILE (TRUE)
246
+ -- !x! SUB_ADD n 1
247
+ -- !x! BEGIN BATCH
248
+ insert into passes values (!!n!!);
249
+ -- !x! END BATCH
250
+ -- !x! IF (EQUALS(!!n!!, 3)) { BREAK }
251
+ -- !x! END LOOP
252
+ ```
253
+
254
+ `passes` ends up with 1, 2 and 3. With the `IF` before `END BATCH`, the third pass's row would be rolled back.
255
+
256
+ When an error or a HALT stops the run inside a batch, the batch is rolled back before an [ON ERROR_HALT EXECUTE SCRIPT](#error_halt_exec) or [ON CANCEL_HALT EXECUTE SCRIPT](#cancel_halt_exec) script runs, so that script's own SQL is committed, such as a row it writes to a log table (unless AUTOCOMMIT is OFF).
230
257
 
231
258
 
232
259
  ## BEGIN SCRIPT and END SCRIPT { #beginscript }
@@ -374,9 +401,32 @@ Metacommands that appear within a BEGIN/END SQL block will be treated as comment
374
401
  BREAK
375
402
  ```
376
403
 
377
- This metacommand will cause an immediate exit from any [LOOP](#loop), [SCRIPT](#beginscript) or [INCLUDEEd](#include) file. If there are multiple levels of these structures active, only the latest level will be exited.
404
+ This metacommand will cause an immediate exit from any [LOOP](#loop), [SCRIPT](#beginscript) or [INCLUDEEd](#include) file. If there are multiple levels of these structures active, only the latest level will be exited:
405
+
406
+ - In a `LOOP`, it ends the loop, and the script carries on after `END LOOP`.
407
+ - In a `SCRIPT`, outside any `LOOP` of its own, it returns from the script. A `SCRIPT` that [EXECUTE SCRIPT](#executescript) repeats with `WHILE` or `UNTIL` stops repeating.
408
+ - In an `INCLUDE`d file, outside any `LOOP` in that file, it leaves the file, and the script that included it carries on, even when the `INCLUDE` is inside a `LOOP`.
378
409
 
379
- If this metacommand is used when none of these structures are active, a warning will be issued.
410
+ A `BREAK` therefore never ends a loop that called the `SCRIPT` or included the file it is in:
411
+
412
+ ```
413
+ -- !x! BEGIN SCRIPT check_one
414
+ -- !x! IF (NOT HASROWS(staging))
415
+ -- !x! BREAK
416
+ -- !x! ENDIF
417
+ -- !x! WRITE "staging has rows"
418
+ -- !x! END SCRIPT
419
+
420
+ -- !x! SUB n 0
421
+ -- !x! LOOP WHILE (IS_GT(3, !{n}!))
422
+ -- !x! SUB_ADD n 1
423
+ -- !x! EXECUTE SCRIPT check_one
424
+ -- !x! END LOOP
425
+ ```
426
+
427
+ Here a `BREAK` in `check_one` skips the rest of that call, and the loop still runs all its passes.
428
+
429
+ A `BREAK` in the main script, outside any of these structures, has nothing to leave. It is a metacommand error: the run stops unless [METACOMMAND_ERROR_HALT](#metacommanderrorhalt) is `OFF`, in which case the script carries on and `METACOMMAND_ERROR()` is true.
380
430
 
381
431
 
382
432
  ## CANCEL_HALT
@@ -953,11 +1003,19 @@ Writes internal state to the log file (`LOG` form) or to the terminal or a file
953
1003
  DISCONNECT [[FROM] <alias>]
954
1004
  ```
955
1005
 
956
- Closes the current database connection, or the connection associated with the alias *alias*, if specified. Aliases are defined by the [CONNECT](#connect) metacommand.
1006
+ Closes the current database connection, or the connection associated with the alias *alias*, if specified. Aliases are defined by the [CONNECT](#connect) metacommand and, as with [USE](#use), match in any case: `DISCONNECT FROM B` closes a connection made `AS b`.
1007
+
1008
+ Disconnecting from an alias that is not connected is an error, so a misspelled alias does not leave the real connection open. Like other metacommand errors, it halts the script unless [METACOMMAND_ERROR_HALT](#metacommanderrorhalt) is OFF. To disconnect only when the alias is connected, test it first:
1009
+
1010
+ ```sql
1011
+ -- !x! IF (ALIAS_DEFINED(staging)) { DISCONNECT FROM staging }
1012
+ ```
1013
+
1014
+ Write the alias in lowercase inside `ALIAS_DEFINED`: aliases are stored in lowercase, and `ALIAS_DEFINED` compares them as written, so `ALIAS_DEFINED(Staging)` is false for a connection made `AS Staging`.
957
1015
 
958
- Attempting to disconnect from the initial database connection will result in an error, and *execsql* will halt.
1016
+ Attempting to disconnect from the initial database connection is also an error.
959
1017
 
960
- Attempting to disconnect from a database that is still in use in a [BATCH](#batch) will result in an error, and *execsql* will halt.
1018
+ So is attempting to disconnect from a database that is still in use in a [BATCH](#batch), that is, one the batch, or a batch around it, has run a statement on. The connection stays open. If the error halts the script, the batch is rolled back; with METACOMMAND_ERROR_HALT OFF the script carries on, but the refusal is an error inside the batch, so END BATCH rolls the batch back instead of committing it (see [BATCH](#batch)). A database the batch has not used can be disconnected inside it.
961
1019
 
962
1020
  Explicitly disconnecting from a database is not necessary before re-using that alias. The [CONNECT](#connect) metacommand will automatically disconnect from a database if its alias is re-used.
963
1021
 
@@ -989,9 +1047,11 @@ ERROR_HALT ON|OFF
989
1047
  ```
990
1048
 
991
1049
 
992
- When ERROR_HALT is set to ON, which is the default, any errors that occur as a result of executing a SQL statement will cause an error message to be displayed immediately, and *execsql* will exit. When ERROR_HALT is set to OFF, then SQL errors will be ignored, but can be evaluated with the [IF SQL_ERROR](#sqlerror) conditional.
1050
+ When ERROR_HALT is set to ON, which is the default, any errors that occur as a result of executing a SQL statement, or committing a [BATCH](#batch) at END BATCH, will cause an error message to be displayed immediately, and *execsql* will exit. When ERROR_HALT is set to OFF, then SQL errors will be ignored, but can be evaluated with the [IF SQL_ERROR](#sqlerror) conditional. A test in an `IF`, `LOOP` or other condition that fails in the database (`HASROWS(no_such_table)`) is not ignored: it stops the run, because no branch can be chosen (see [METACOMMAND_ERROR_HALT](#metacommanderrorhalt)).
1051
+
1052
+ A statement whose commit fails (for example, on a deferred foreign key that is checked at COMMIT) is an SQL error like any other, and its transaction is rolled back, so no later commit stores it.
993
1053
 
994
- When ERROR_HALT is set to OFF inside a transaction, any SQL error will ordinarily cause the entire transaction to fail.
1054
+ When ERROR_HALT is set to OFF inside a transaction, any SQL error will ordinarily cause the entire transaction to fail. Inside a [BATCH](#batch), an error means END BATCH rolls the batch back instead of committing it, and reports an SQL error of its own; if ERROR_HALT is ON at END BATCH, the run stops there.
995
1055
 
996
1056
 
997
1057
  ## EXECUTE { #execute }
@@ -1850,7 +1910,7 @@ SQL_ERROR()
1850
1910
 
1851
1911
  Evaluates whether the previous SQL statement generated an error. Errors will result from badly-formed SQL, reference to non-existent database objects, lack of permissions, or database locks. A query (e.g., an update query) that does not do exactly what you expect it to will not necessarily cause an error to occur that can be identified with this statement. This test for SQL errors will only be effective if the [ERROR_HALT OFF](#error_halt) metacommand has previously been issued.
1852
1912
 
1853
- Errors in metacommands and some other errors encountered by *execsql* will cause the program to halt immediately, regardless of the setting of [ERROR_HALT](#error_halt) or the use of the IF(SQL_ERROR()) test.
1913
+ Errors in metacommands and some other errors encountered by *execsql* will cause the program to halt immediately, regardless of the setting of [ERROR_HALT](#error_halt) or the use of the IF(SQL_ERROR()) test. A commit that fails at END BATCH is an SQL error, not a metacommand error: ERROR_HALT governs it. END BATCH clears SQL_ERROR() before its commit, as an SQL statement does, so right after END BATCH it says whether the batch was committed: it is set when the commit fails and when an error earlier in the batch, from an SQL statement or a metacommand, kept it from being committed.
1854
1914
 
1855
1915
 
1856
1916
  ### *STARTS_WITH*
@@ -2143,7 +2203,9 @@ The [BREAK](#break) metacommand can be used to exit from a loop at any time.
2143
2203
  METACOMMAND_ERROR_HALT ON|OFF
2144
2204
  ```
2145
2205
 
2146
- When METACOMMAND_ERROR_HALT is set to ON, which is the default, any errors that occur during execution of a metacommand will cause an error message to be displayed immediately, and *execsql* to halt. When METACOMMAND_ERROR_HALT is set to OFF, then metacommand errors will be ignored, but can be evaluated with the [IF METACOMMAND_ERROR](#metacommanderror) conditional; `$LAST_ERROR` and `$ERROR_MESSAGE` hold the failed metacommand and its message.
2206
+ When METACOMMAND_ERROR_HALT is set to ON, which is the default, any errors that occur during execution of a metacommand will cause an error message to be displayed immediately, and *execsql* to halt. When METACOMMAND_ERROR_HALT is set to OFF, then metacommand errors will be ignored, but can be evaluated with the [IF METACOMMAND_ERROR](#metacommanderror) conditional; `$LAST_ERROR` and `$ERROR_MESSAGE` hold the failed metacommand and its message. Inside a [BATCH](#batch), a metacommand error that the script carries on from still keeps the batch from being committed: END BATCH rolls it back and reports an SQL error.
2207
+
2208
+ A condition that cannot be evaluated is not covered by this setting: an `IF`, `ELSEIF`, `ANDIF`, `ORIF`, `LOOP` or `EXECUTE SCRIPT … WHILE` / `UNTIL` whose condition names an unknown test or is malformed (`IF (NO_SUCH_FN(x))`), or whose test fails in the database (`HASROWS(no_such_table)`), stops the run even with METACOMMAND_ERROR_HALT OFF, because no branch can be chosen. `execsql lint` reports an unknown test or malformed condition before a run (P004); a test that fails in the database shows up only when the script runs.
2147
2209
 
2148
2210
  The METACOMMAND_ERROR_HALT metacommand does not itself set or reset the internal flag that indicates whether a metacommand has encountered an error. This is so that a "METACOMMAND_ERROR_HALT Off" command can be used immediately after a potentially-failing metacommand and not alter the error flag that is set by the previous command. Specifically, constructions like this:
2149
2211
 
@@ -2200,6 +2262,8 @@ If the specified script runs after the user cancels the main script, it will cle
2200
2262
 
2201
2263
  The intended use of this metacommand is to allow cleanup of staging tables and any other database objects that should be removed when the main script terminates.
2202
2264
 
2265
+ If the user cancels inside a [BATCH](#batch), the batch is rolled back before the script runs, and the script's own SQL is committed as usual (not while [AUTOCOMMIT](#autocommit) is OFF).
2266
+
2203
2267
 
2204
2268
  ## ON CANCEL_HALT WRITE { #cancel_halt_write }
2205
2269
 
@@ -2267,6 +2331,8 @@ If the specified script runs after an error occurs, it will clear its own specif
2267
2331
 
2268
2332
  The intended use of this metacommand is to allow cleanup of staging tables and any other database objects that would be removed if the main script terminated normally.
2269
2333
 
2334
+ If the error happens inside a [BATCH](#batch), the batch is rolled back before the script runs, and the script's own SQL is committed as usual (not while [AUTOCOMMIT](#autocommit) is OFF).
2335
+
2270
2336
 
2271
2337
  ## ON ERROR_HALT WRITE { #error_halt_write }
2272
2338
 
@@ -161,9 +161,11 @@ choice you make.
161
161
 
162
162
  Containment roots are opt-in. When configured, paths must resolve under the configured root; attempts to escape with `../`, absolute paths, drive letters, or UNC paths are rejected.
163
163
 
164
+ An `INCLUDE` refused by `include_root` stops the run even with [`METACOMMAND_ERROR_HALT OFF`](metacommands.md#metacommanderrorhalt): the refusal is a security boundary, not a script error to carry on from, so the statements after it never run without the file they expected.
165
+
164
166
  | Setting | Applies to | Default |
165
167
  | --------------- | ----------------------------------------- | ------------ |
166
- | `include_root` | `INCLUDE` and `EXECUTE SCRIPT` targets | unrestricted |
168
+ | `include_root` | `INCLUDE` files | unrestricted |
167
169
  | `serve_root` | `SERVE` targets | unrestricted |
168
170
  | `template_root` | Jinja2 and `string.Template` loader paths | unrestricted |
169
171
 
@@ -14,6 +14,8 @@ The \<match_string> identifies the substitution variable; the \<replacement_stri
14
14
  - `!'!name!'!` — wrap the value in single quotes, doubling any embedded apostrophe; on a MySQL or MariaDB connection, which reads `\` in a string literal as an escape, backslashes are doubled too. The value is stored exactly as written (`C:\data\new` stays `C:\data\new`). Suitable for SQL string literals containing user data. On PostgreSQL, `E!'!name!'!` (an escape string) doubles backslashes too, so it stores the same value as `!'!name!'!`; the `E` is not needed.
15
15
  - `!"!name!"!` — wrap the value in double quotes. Suitable for SQL quoted identifiers, or for metacommand arguments that must be quoted.
16
16
 
17
+ A variable can supply a whole metacommand (`-- !x! !!cmd!!` runs whatever metacommand `cmd` holds), except `INCLUDE`, `EXECUTE SCRIPT` (or `EXEC SCRIPT` / `RUN SCRIPT`) and the block metacommands (`IF`, `ELSEIF`, `ANDIF`, `ORIF`, `ELSE`, `ENDIF`, `LOOP`, `END LOOP`, `BEGIN BATCH`, `END BATCH`, `BEGIN SCRIPT` (or `CREATE SCRIPT`), `END SCRIPT`, `BEGIN SQL`, `END SQL`): execsql2 reads those when it parses the script, before substitution, so one supplied by a variable does not run. Most of these are a metacommand error, which `METACOMMAND_ERROR_HALT OFF` skips without printing anything (test for it with `METACOMMAND_ERROR()`; `execsql.run()` still lists it in `result.errors`); `END LOOP`, `BEGIN` / `CREATE` / `END SCRIPT` and `BEGIN` / `END SQL` stop the run whatever that setting says. Write the metacommand in the script and put the variable in its argument: `INCLUDE !!file!!`, `EXECUTE SCRIPT !!name!!`, `IF (!!condition!!)`.
18
+
17
19
  Variables can also be set before the script starts: with `--var NAME=VALUE` on the [command line](../getting-started/syntax.md#options), or in the `[variables]` section of a [config file](configuration.md#configuration). `--var` wins over the config file, and a `SUB` in the script can reassign either.
18
20
 
19
21
  For example, to use a data variable that may contain apostrophes in a SQL string literal:
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "execsql-syntax",
3
- "version": "2.35.0",
3
+ "version": "2.37.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "execsql-syntax",
9
- "version": "2.35.0",
9
+ "version": "2.37.0",
10
10
  "license": "GPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "vscode-languageclient": "10.1.2"
@@ -2,7 +2,7 @@
2
2
  "name": "execsql-syntax",
3
3
  "displayName": "execsql",
4
4
  "description": "Syntax highlighting, lint findings, completion, hover, navigation, quick fixes and formatting for execsql scripts.",
5
- "version": "2.35.0",
5
+ "version": "2.37.0",
6
6
  "publisher": "geocoug",
7
7
  "license": "GPL-3.0-or-later",
8
8
  "icon": "icon.png",