execsql2 2.34.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 (690) hide show
  1. execsql2-2.37.0/.gitattributes +4 -0
  2. {execsql2-2.34.0 → execsql2-2.37.0}/CHANGELOG.md +62 -0
  3. {execsql2-2.34.0 → execsql2-2.37.0}/CONTRIBUTING.md +13 -0
  4. {execsql2-2.34.0 → execsql2-2.37.0}/PKG-INFO +2 -2
  5. {execsql2-2.34.0 → execsql2-2.37.0}/README.md +1 -1
  6. {execsql2-2.34.0 → execsql2-2.37.0}/docs/about/divergence.md +36 -20
  7. {execsql2-2.34.0 → execsql2-2.37.0}/docs/guides/debugging.md +9 -9
  8. {execsql2-2.34.0 → execsql2-2.37.0}/docs/guides/formatter.md +1 -1
  9. {execsql2-2.34.0 → execsql2-2.37.0}/docs/reference/configuration.md +8 -4
  10. {execsql2-2.34.0 → execsql2-2.37.0}/docs/reference/lint.md +9 -1
  11. {execsql2-2.34.0 → execsql2-2.37.0}/docs/reference/metacommands.md +92 -11
  12. {execsql2-2.34.0 → execsql2-2.37.0}/docs/reference/security.md +3 -1
  13. {execsql2-2.34.0 → execsql2-2.37.0}/docs/reference/substitution_vars.md +2 -0
  14. {execsql2-2.34.0 → execsql2-2.37.0}/extras/vscode-execsql/package-lock.json +2 -2
  15. {execsql2-2.34.0 → execsql2-2.37.0}/extras/vscode-execsql/package.json +1 -1
  16. {execsql2-2.34.0 → execsql2-2.37.0}/extras/vscode-execsql/syntaxes/execsql.tmLanguage.json +1 -1
  17. {execsql2-2.34.0 → execsql2-2.37.0}/pyproject.toml +2 -2
  18. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/api.py +17 -8
  19. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/lint.py +54 -6
  20. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/run.py +5 -10
  21. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/config.py +2 -0
  22. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/data/execsql.conf.template +17 -7
  23. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/base.py +12 -2
  24. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/duckdb.py +8 -1
  25. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/debug/repl.py +2 -2
  26. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/connect.py +10 -9
  27. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/data.py +7 -1
  28. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/dispatch.py +7 -0
  29. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/io_fileops.py +6 -3
  30. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/io_write.py +3 -1
  31. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/reference.py +1 -0
  32. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/script_ext.py +13 -10
  33. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/system.py +13 -6
  34. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/models.py +30 -4
  35. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/script/ast.py +21 -0
  36. execsql2-2.37.0/src/execsql/script/control.py +127 -0
  37. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/script/executor.py +379 -229
  38. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/script/parser.py +102 -52
  39. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/state.py +23 -0
  40. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/errors.py +24 -6
  41. execsql2-2.37.0/src/execsql/utils/sigterm.py +154 -0
  42. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_cli_e2e.py +11 -0
  43. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_lint.py +50 -0
  44. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_manifest.py +1 -1
  45. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_sigterm.py +41 -0
  46. {execsql2-2.34.0 → execsql2-2.37.0}/tests/conftest.py +16 -0
  47. execsql2-2.37.0/tests/corpus/cases/batch_and_autocommit/script.sql +16 -0
  48. execsql2-2.37.0/tests/corpus/cases/batch_commit_fails/script.sql +21 -0
  49. execsql2-2.37.0/tests/corpus/cases/batch_inner_left_by_break/script.sql +14 -0
  50. execsql2-2.37.0/tests/corpus/cases/batch_left_by_break/script.sql +9 -0
  51. execsql2-2.37.0/tests/corpus/cases/batch_left_by_error/script.sql +12 -0
  52. execsql2-2.37.0/tests/corpus/cases/batch_left_by_halt/script.sql +7 -0
  53. execsql2-2.37.0/tests/corpus/cases/batch_left_under_autocommit_off/script.sql +13 -0
  54. execsql2-2.37.0/tests/corpus/cases/batch_metacommand_sql_fails/script.sql +13 -0
  55. execsql2-2.37.0/tests/corpus/cases/batch_nested_commit_fails/script.sql +15 -0
  56. execsql2-2.37.0/tests/corpus/cases/batch_nested_commit_fails_carry_on/script.sql +22 -0
  57. execsql2-2.37.0/tests/corpus/cases/batch_sql_error_after_end_batch/script.sql +9 -0
  58. execsql2-2.37.0/tests/corpus/cases/batch_statement_fails/script.sql +12 -0
  59. execsql2-2.37.0/tests/corpus/cases/begin_sql_block/script.sql +11 -0
  60. execsql2-2.37.0/tests/corpus/cases/boolean_and_empty_config/data.csv +4 -0
  61. execsql2-2.37.0/tests/corpus/cases/boolean_and_empty_config/script.sql +13 -0
  62. execsql2-2.37.0/tests/corpus/cases/break_at_top_level/script.sql +4 -0
  63. execsql2-2.37.0/tests/corpus/cases/break_in_inline_if/script.sql +8 -0
  64. execsql2-2.37.0/tests/corpus/cases/break_leaves_script_and_include/part.sql +3 -0
  65. execsql2-2.37.0/tests/corpus/cases/break_leaves_script_and_include/script.sql +51 -0
  66. execsql2-2.37.0/tests/corpus/cases/cd_relative_paths/script.sql +5 -0
  67. execsql2-2.37.0/tests/corpus/cases/cd_relative_paths/sub/data.csv +3 -0
  68. execsql2-2.37.0/tests/corpus/cases/commit_fails/script.sql +9 -0
  69. execsql2-2.37.0/tests/corpus/cases/condition_error_block_if/script.sql +20 -0
  70. execsql2-2.37.0/tests/corpus/cases/condition_error_database/script.sql +6 -0
  71. execsql2-2.37.0/tests/corpus/cases/condition_error_script_while/script.sql +8 -0
  72. execsql2-2.37.0/tests/corpus/cases/conditions_more/marker.txt +1 -0
  73. execsql2-2.37.0/tests/corpus/cases/conditions_more/script.sql +30 -0
  74. execsql2-2.37.0/tests/corpus/cases/config_column_headers/duplicate_headers.csv +3 -0
  75. execsql2-2.37.0/tests/corpus/cases/config_column_headers/empty_column.csv +3 -0
  76. execsql2-2.37.0/tests/corpus/cases/config_column_headers/headers.csv +3 -0
  77. execsql2-2.37.0/tests/corpus/cases/config_column_headers/missing_headers.csv +2 -0
  78. execsql2-2.37.0/tests/corpus/cases/config_column_headers/script.sql +16 -0
  79. execsql2-2.37.0/tests/corpus/cases/config_export/script.sql +14 -0
  80. execsql2-2.37.0/tests/corpus/cases/config_import_rows/numbers.csv +3 -0
  81. execsql2-2.37.0/tests/corpus/cases/config_import_rows/rows.csv +5 -0
  82. execsql2-2.37.0/tests/corpus/cases/config_import_rows/script.sql +12 -0
  83. execsql2-2.37.0/tests/corpus/cases/copy_and_import_errors/data.csv +3 -0
  84. execsql2-2.37.0/tests/corpus/cases/copy_and_import_errors/script.sql +13 -0
  85. execsql2-2.37.0/tests/corpus/cases/copy_between_databases/script.sql +17 -0
  86. execsql2-2.37.0/tests/corpus/cases/counters/script.sql +11 -0
  87. execsql2-2.37.0/tests/corpus/cases/decimal_digits/long.csv +3 -0
  88. execsql2-2.37.0/tests/corpus/cases/decimal_digits/script.sql +3 -0
  89. execsql2-2.37.0/tests/corpus/cases/decimal_digits/short.csv +4 -0
  90. execsql2-2.37.0/tests/corpus/cases/deferred_substitution/script.sql +11 -0
  91. execsql2-2.37.0/tests/corpus/cases/directive_from_variable/part.sql +1 -0
  92. execsql2-2.37.0/tests/corpus/cases/directive_from_variable/script.sql +14 -0
  93. execsql2-2.37.0/tests/corpus/cases/disconnect_checks/script.sql +38 -0
  94. execsql2-2.37.0/tests/corpus/cases/error_flags/script.sql +13 -0
  95. execsql2-2.37.0/tests/corpus/cases/error_halt_off/script.sql +13 -0
  96. execsql2-2.37.0/tests/corpus/cases/error_stops_script/script.sql +7 -0
  97. execsql2-2.37.0/tests/corpus/cases/execute_script_args/script.sql +21 -0
  98. execsql2-2.37.0/tests/corpus/cases/export_more_formats/script.sql +10 -0
  99. execsql2-2.37.0/tests/corpus/cases/export_query_append/script.sql +8 -0
  100. execsql2-2.37.0/tests/corpus/cases/export_structured_formats/script.sql +7 -0
  101. execsql2-2.37.0/tests/corpus/cases/export_text_formats/script.sql +9 -0
  102. execsql2-2.37.0/tests/corpus/cases/halt_exit_status/script.sql +5 -0
  103. execsql2-2.37.0/tests/corpus/cases/if_conditions/script.sql +42 -0
  104. execsql2-2.37.0/tests/corpus/cases/import_csv_existing/data.csv +3 -0
  105. execsql2-2.37.0/tests/corpus/cases/import_csv_existing/script.sql +6 -0
  106. execsql2-2.37.0/tests/corpus/cases/import_csv_new/data.csv +4 -0
  107. execsql2-2.37.0/tests/corpus/cases/import_csv_new/data.tsv +3 -0
  108. execsql2-2.37.0/tests/corpus/cases/import_csv_new/script.sql +4 -0
  109. execsql2-2.37.0/tests/corpus/cases/import_file_column/note.txt +2 -0
  110. execsql2-2.37.0/tests/corpus/cases/import_file_column/script.sql +3 -0
  111. execsql2-2.37.0/tests/corpus/cases/include_file/part.sql +3 -0
  112. execsql2-2.37.0/tests/corpus/cases/include_file/script.sql +6 -0
  113. execsql2-2.37.0/tests/corpus/cases/inline_directives_and_condition_errors/part.sql +1 -0
  114. execsql2-2.37.0/tests/corpus/cases/inline_directives_and_condition_errors/script.sql +15 -0
  115. execsql2-2.37.0/tests/corpus/cases/local_and_outer_vars/script.sql +14 -0
  116. execsql2-2.37.0/tests/corpus/cases/loop_while_until/script.sql +28 -0
  117. execsql2-2.37.0/tests/corpus/cases/on_error_halt_execute/script.sql +9 -0
  118. execsql2-2.37.0/tests/corpus/cases/on_error_halt_write/script.sql +7 -0
  119. execsql2-2.37.0/tests/corpus/cases/script_extend_and_write/script.sql +15 -0
  120. execsql2-2.37.0/tests/corpus/cases/select_sub_subdata/script.sql +9 -0
  121. execsql2-2.37.0/tests/corpus/cases/sub_backslash/script.sql +7 -0
  122. execsql2-2.37.0/tests/corpus/cases/sub_basic/script.sql +18 -0
  123. execsql2-2.37.0/tests/corpus/cases/sub_encrypt_decrypt/script.sql +5 -0
  124. execsql2-2.37.0/tests/corpus/cases/sub_ini/script.sql +5 -0
  125. execsql2-2.37.0/tests/corpus/cases/sub_ini/settings.ini +6 -0
  126. execsql2-2.37.0/tests/corpus/cases/sub_quoting/script.sql +6 -0
  127. execsql2-2.37.0/tests/corpus/cases/sub_quoting_upstream_idiom/script.sql +6 -0
  128. execsql2-2.37.0/tests/corpus/cases/sub_tempfile/script.sql +6 -0
  129. execsql2-2.37.0/tests/corpus/cases/system_vars/script.sql +12 -0
  130. execsql2-2.37.0/tests/corpus/cases/unsubstituted_warning/script.sql +7 -0
  131. execsql2-2.37.0/tests/corpus/cases/wait_until_and_cancel_halt/script.sql +6 -0
  132. execsql2-2.37.0/tests/corpus/cases/write_console/script.sql +6 -0
  133. execsql2-2.37.0/tests/corpus/cases/write_create_table/data.csv +3 -0
  134. execsql2-2.37.0/tests/corpus/cases/write_create_table/script.sql +2 -0
  135. execsql2-2.37.0/tests/corpus/cases/zip_files/note.txt +1 -0
  136. execsql2-2.37.0/tests/corpus/cases/zip_files/script.sql +7 -0
  137. execsql2-2.37.0/tests/corpus/changes.json +1334 -0
  138. execsql2-2.37.0/tests/corpus/record.py +53 -0
  139. execsql2-2.37.0/tests/corpus/results/batch_and_autocommit.json +37 -0
  140. execsql2-2.37.0/tests/corpus/results/batch_commit_fails.json +64 -0
  141. execsql2-2.37.0/tests/corpus/results/batch_inner_left_by_break.json +37 -0
  142. execsql2-2.37.0/tests/corpus/results/batch_left_by_break.json +18 -0
  143. execsql2-2.37.0/tests/corpus/results/batch_left_by_error.json +27 -0
  144. execsql2-2.37.0/tests/corpus/results/batch_left_by_halt.json +25 -0
  145. execsql2-2.37.0/tests/corpus/results/batch_left_under_autocommit_off.json +31 -0
  146. execsql2-2.37.0/tests/corpus/results/batch_metacommand_sql_fails.json +33 -0
  147. execsql2-2.37.0/tests/corpus/results/batch_nested_commit_fails.json +36 -0
  148. execsql2-2.37.0/tests/corpus/results/batch_nested_commit_fails_carry_on.json +49 -0
  149. execsql2-2.37.0/tests/corpus/results/batch_sql_error_after_end_batch.json +10 -0
  150. execsql2-2.37.0/tests/corpus/results/batch_statement_fails.json +33 -0
  151. execsql2-2.37.0/tests/corpus/results/begin_sql_block.json +53 -0
  152. execsql2-2.37.0/tests/corpus/results/boolean_and_empty_config.json +389 -0
  153. execsql2-2.37.0/tests/corpus/results/break_at_top_level.json +10 -0
  154. execsql2-2.37.0/tests/corpus/results/break_in_inline_if.json +10 -0
  155. execsql2-2.37.0/tests/corpus/results/break_leaves_script_and_include.json +10 -0
  156. execsql2-2.37.0/tests/corpus/results/cd_relative_paths.json +46 -0
  157. execsql2-2.37.0/tests/corpus/results/commit_fails.json +43 -0
  158. execsql2-2.37.0/tests/corpus/results/condition_error_block_if.json +10 -0
  159. execsql2-2.37.0/tests/corpus/results/condition_error_database.json +10 -0
  160. execsql2-2.37.0/tests/corpus/results/condition_error_script_while.json +8 -0
  161. execsql2-2.37.0/tests/corpus/results/conditions_more.json +36 -0
  162. execsql2-2.37.0/tests/corpus/results/config_column_headers.json +150 -0
  163. execsql2-2.37.0/tests/corpus/results/config_export.json +47 -0
  164. execsql2-2.37.0/tests/corpus/results/config_import_rows.json +145 -0
  165. execsql2-2.37.0/tests/corpus/results/copy_and_import_errors.json +79 -0
  166. execsql2-2.37.0/tests/corpus/results/copy_between_databases.json +355 -0
  167. execsql2-2.37.0/tests/corpus/results/counters.json +55 -0
  168. execsql2-2.37.0/tests/corpus/results/decimal_digits.json +10 -0
  169. execsql2-2.37.0/tests/corpus/results/deferred_substitution.json +39 -0
  170. execsql2-2.37.0/tests/corpus/results/directive_from_variable.json +10 -0
  171. execsql2-2.37.0/tests/corpus/results/disconnect_checks.json +24 -0
  172. execsql2-2.37.0/tests/corpus/results/error_flags.json +33 -0
  173. execsql2-2.37.0/tests/corpus/results/error_halt_off.json +39 -0
  174. execsql2-2.37.0/tests/corpus/results/error_stops_script.json +27 -0
  175. execsql2-2.37.0/tests/corpus/results/execute_script_args.json +51 -0
  176. execsql2-2.37.0/tests/corpus/results/export_more_formats.json +77 -0
  177. execsql2-2.37.0/tests/corpus/results/export_query_append.json +58 -0
  178. execsql2-2.37.0/tests/corpus/results/export_structured_formats.json +72 -0
  179. execsql2-2.37.0/tests/corpus/results/export_text_formats.json +92 -0
  180. execsql2-2.37.0/tests/corpus/results/halt_exit_status.json +25 -0
  181. execsql2-2.37.0/tests/corpus/results/if_conditions.json +33 -0
  182. execsql2-2.37.0/tests/corpus/results/import_csv_existing.json +113 -0
  183. execsql2-2.37.0/tests/corpus/results/import_csv_new.json +183 -0
  184. execsql2-2.37.0/tests/corpus/results/import_file_column.json +25 -0
  185. execsql2-2.37.0/tests/corpus/results/include_file.json +33 -0
  186. execsql2-2.37.0/tests/corpus/results/inline_directives_and_condition_errors.json +10 -0
  187. execsql2-2.37.0/tests/corpus/results/local_and_outer_vars.json +37 -0
  188. execsql2-2.37.0/tests/corpus/results/loop_while_until.json +51 -0
  189. execsql2-2.37.0/tests/corpus/results/on_error_halt_execute.json +27 -0
  190. execsql2-2.37.0/tests/corpus/results/on_error_halt_write.json +20 -0
  191. execsql2-2.37.0/tests/corpus/results/script_extend_and_write.json +40 -0
  192. execsql2-2.37.0/tests/corpus/results/select_sub_subdata.json +45 -0
  193. execsql2-2.37.0/tests/corpus/results/sub_backslash.json +18 -0
  194. execsql2-2.37.0/tests/corpus/results/sub_basic.json +45 -0
  195. execsql2-2.37.0/tests/corpus/results/sub_encrypt_decrypt.json +10 -0
  196. execsql2-2.37.0/tests/corpus/results/sub_ini.json +10 -0
  197. execsql2-2.37.0/tests/corpus/results/sub_quoting.json +22 -0
  198. execsql2-2.37.0/tests/corpus/results/sub_quoting_upstream_idiom.json +27 -0
  199. execsql2-2.37.0/tests/corpus/results/sub_tempfile.json +10 -0
  200. execsql2-2.37.0/tests/corpus/results/system_vars.json +39 -0
  201. execsql2-2.37.0/tests/corpus/results/unsubstituted_warning.json +27 -0
  202. execsql2-2.37.0/tests/corpus/results/wait_until_and_cancel_halt.json +10 -0
  203. execsql2-2.37.0/tests/corpus/results/write_console.json +10 -0
  204. execsql2-2.37.0/tests/corpus/results/write_create_table.json +10 -0
  205. execsql2-2.37.0/tests/corpus/results/zip_files.json +51 -0
  206. execsql2-2.37.0/tests/corpus/runner.py +156 -0
  207. execsql2-2.37.0/tests/corpus/test_script_corpus.py +74 -0
  208. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/lint/every_metacommand.sql +1 -0
  209. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_transactions.py +67 -2
  210. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands.py +2 -2
  211. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_extended.py +3 -5
  212. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_fileops_extra.py +1 -1
  213. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_io.py +1 -1
  214. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_script_ext.py +1 -1
  215. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_system.py +42 -17
  216. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_log_secrets.py +3 -1
  217. execsql2-2.37.0/tests/test_break.py +80 -0
  218. execsql2-2.37.0/tests/test_disconnect.py +130 -0
  219. execsql2-2.37.0/tests/test_end_batch_commit.py +268 -0
  220. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_error_messages.py +5 -5
  221. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_executor.py +11 -11
  222. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_executor_inprocess.py +5 -0
  223. execsql2-2.37.0/tests/test_failed_commit.py +162 -0
  224. execsql2-2.37.0/tests/test_include_errors.py +349 -0
  225. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_interactive.py +28 -1
  226. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_models.py +54 -32
  227. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_script.py +117 -0
  228. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_state.py +23 -0
  229. execsql2-2.37.0/tests/utils/__init__.py +0 -0
  230. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_errors_extra.py +38 -0
  231. execsql2-2.37.0/tests/utils/test_sigterm.py +319 -0
  232. {execsql2-2.34.0 → execsql2-2.37.0}/uv.lock +1 -1
  233. execsql2-2.34.0/src/execsql/script/control.py +0 -67
  234. {execsql2-2.34.0 → execsql2-2.37.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  235. {execsql2-2.34.0 → execsql2-2.37.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  236. {execsql2-2.34.0 → execsql2-2.37.0}/.github/dependabot.yml +0 -0
  237. {execsql2-2.34.0 → execsql2-2.37.0}/.github/workflows/ci-cd.yml +0 -0
  238. {execsql2-2.34.0 → execsql2-2.37.0}/.gitignore +0 -0
  239. {execsql2-2.34.0 → execsql2-2.37.0}/.pre-commit-config.yaml +0 -0
  240. {execsql2-2.34.0 → execsql2-2.37.0}/.pre-commit-hooks.yaml +0 -0
  241. {execsql2-2.34.0 → execsql2-2.37.0}/.python-version +0 -0
  242. {execsql2-2.34.0 → execsql2-2.37.0}/.readthedocs.yaml +0 -0
  243. {execsql2-2.34.0 → execsql2-2.37.0}/LICENSE.txt +0 -0
  244. {execsql2-2.34.0 → execsql2-2.37.0}/NOTICE +0 -0
  245. {execsql2-2.34.0 → execsql2-2.37.0}/SECURITY.md +0 -0
  246. {execsql2-2.34.0 → execsql2-2.37.0}/docs/about/contributors.md +0 -0
  247. {execsql2-2.34.0 → execsql2-2.37.0}/docs/about/copyright.md +0 -0
  248. {execsql2-2.34.0 → execsql2-2.37.0}/docs/api/cli.md +0 -0
  249. {execsql2-2.34.0 → execsql2-2.37.0}/docs/api/db.md +0 -0
  250. {execsql2-2.34.0 → execsql2-2.37.0}/docs/api/exporters.md +0 -0
  251. {execsql2-2.34.0 → execsql2-2.37.0}/docs/api/importers.md +0 -0
  252. {execsql2-2.34.0 → execsql2-2.37.0}/docs/api/index.md +0 -0
  253. {execsql2-2.34.0 → execsql2-2.37.0}/docs/api/metacommands.md +0 -0
  254. {execsql2-2.34.0 → execsql2-2.37.0}/docs/dev/adding_db_adapters.md +0 -0
  255. {execsql2-2.34.0 → execsql2-2.37.0}/docs/dev/adding_exporters.md +0 -0
  256. {execsql2-2.34.0 → execsql2-2.37.0}/docs/dev/adding_importers.md +0 -0
  257. {execsql2-2.34.0 → execsql2-2.37.0}/docs/dev/adding_metacommands.md +0 -0
  258. {execsql2-2.34.0 → execsql2-2.37.0}/docs/dev/architecture.md +0 -0
  259. {execsql2-2.34.0 → execsql2-2.37.0}/docs/dev/releasing.md +0 -0
  260. {execsql2-2.34.0 → execsql2-2.37.0}/docs/getting-started/installation.md +0 -0
  261. {execsql2-2.34.0 → execsql2-2.37.0}/docs/getting-started/requirements.md +0 -0
  262. {execsql2-2.34.0 → execsql2-2.37.0}/docs/getting-started/syntax.md +0 -0
  263. {execsql2-2.34.0 → execsql2-2.37.0}/docs/guides/documentation.md +0 -0
  264. {execsql2-2.34.0 → execsql2-2.37.0}/docs/guides/editors.md +0 -0
  265. {execsql2-2.34.0 → execsql2-2.37.0}/docs/guides/encoding.md +0 -0
  266. {execsql2-2.34.0 → execsql2-2.37.0}/docs/guides/examples.md +0 -0
  267. {execsql2-2.34.0 → execsql2-2.37.0}/docs/guides/logging.md +0 -0
  268. {execsql2-2.34.0 → execsql2-2.37.0}/docs/guides/sql_syntax.md +0 -0
  269. {execsql2-2.34.0 → execsql2-2.37.0}/docs/guides/usage.md +0 -0
  270. {execsql2-2.34.0 → execsql2-2.37.0}/docs/guides/using_scripts.md +0 -0
  271. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/Compare_planets.png +0 -0
  272. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/actions.png +0 -0
  273. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/actions2.png +0 -0
  274. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/checkboxes.png +0 -0
  275. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/connect.png +0 -0
  276. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/data_error1_screenshot.jpg +0 -0
  277. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/execsql_logo_01.png +0 -0
  278. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/fatals.png +0 -0
  279. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/pause_terminal_sm.png +0 -0
  280. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/set_build_commands.jpg +0 -0
  281. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/unit_conversions_029.png +0 -0
  282. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/unmatched.png +0 -0
  283. {execsql2-2.34.0 → execsql2-2.37.0}/docs/images/vim_execsql_highlight.png +0 -0
  284. {execsql2-2.34.0 → execsql2-2.37.0}/docs/index.md +0 -0
  285. {execsql2-2.34.0 → execsql2-2.37.0}/docs/templates/compare.md +0 -0
  286. {execsql2-2.34.0 → execsql2-2.37.0}/docs/templates/glossary.md +0 -0
  287. {execsql2-2.34.0 → execsql2-2.37.0}/docs/templates/index.md +0 -0
  288. {execsql2-2.34.0 → execsql2-2.37.0}/docs/templates/upsert.md +0 -0
  289. {execsql2-2.34.0 → execsql2-2.37.0}/extras/plugin-template/README.md +0 -0
  290. {execsql2-2.34.0 → execsql2-2.37.0}/extras/plugin-template/pyproject.toml +0 -0
  291. {execsql2-2.34.0 → execsql2-2.37.0}/extras/plugin-template/src/execsql_plugin_YOURNAME/__init__.py +0 -0
  292. {execsql2-2.34.0 → execsql2-2.37.0}/extras/plugin-template/tests/test_plugin.py.example +0 -0
  293. {execsql2-2.34.0 → execsql2-2.37.0}/extras/vscode-execsql/.vscodeignore +0 -0
  294. {execsql2-2.34.0 → execsql2-2.37.0}/extras/vscode-execsql/LICENSE.txt +0 -0
  295. {execsql2-2.34.0 → execsql2-2.37.0}/extras/vscode-execsql/README.md +0 -0
  296. {execsql2-2.34.0 → execsql2-2.37.0}/extras/vscode-execsql/extension.js +0 -0
  297. {execsql2-2.34.0 → execsql2-2.37.0}/extras/vscode-execsql/icon.png +0 -0
  298. {execsql2-2.34.0 → execsql2-2.37.0}/justfile +0 -0
  299. {execsql2-2.34.0 → execsql2-2.37.0}/scripts/benchmarks/README.md +0 -0
  300. {execsql2-2.34.0 → execsql2-2.37.0}/scripts/benchmarks/results/.gitignore +0 -0
  301. {execsql2-2.34.0 → execsql2-2.37.0}/scripts/benchmarks/run_benchmarks.py +0 -0
  302. {execsql2-2.34.0 → execsql2-2.37.0}/scripts/generate_vscode_grammar.py +0 -0
  303. {execsql2-2.34.0 → execsql2-2.37.0}/scripts/release_notes.py +0 -0
  304. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/__init__.py +0 -0
  305. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/__main__.py +0 -0
  306. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/__init__.py +0 -0
  307. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/application.py +0 -0
  308. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/commands/__init__.py +0 -0
  309. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/commands/config.py +0 -0
  310. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/commands/format.py +0 -0
  311. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/commands/init.py +0 -0
  312. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/commands/lint.py +0 -0
  313. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/commands/listing.py +0 -0
  314. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/commands/lsp.py +0 -0
  315. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/commands/run.py +0 -0
  316. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/dispatch.py +0 -0
  317. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/dsn.py +0 -0
  318. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/help.py +0 -0
  319. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/cli/options.py +0 -0
  320. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/config_validation.py +0 -0
  321. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/data/__init__.py +0 -0
  322. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/data/script_header.sql +0 -0
  323. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/__init__.py +0 -0
  324. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/access.py +0 -0
  325. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/dsn.py +0 -0
  326. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/factory.py +0 -0
  327. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/firebird.py +0 -0
  328. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/mysql.py +0 -0
  329. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/odbc.py +0 -0
  330. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/oracle.py +0 -0
  331. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/postgres.py +0 -0
  332. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/sqlite.py +0 -0
  333. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/sqlserver.py +0 -0
  334. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/target_types.py +0 -0
  335. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/db/tiers.py +0 -0
  336. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/debug/__init__.py +0 -0
  337. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exceptions.py +0 -0
  338. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/__init__.py +0 -0
  339. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/base.py +0 -0
  340. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/delimited.py +0 -0
  341. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/duckdb.py +0 -0
  342. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/feather.py +0 -0
  343. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/html.py +0 -0
  344. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/json.py +0 -0
  345. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/latex.py +0 -0
  346. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/markdown.py +0 -0
  347. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/ods.py +0 -0
  348. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/parquet.py +0 -0
  349. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/pretty.py +0 -0
  350. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/protocol.py +0 -0
  351. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/raw.py +0 -0
  352. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/sqlite.py +0 -0
  353. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/templates.py +0 -0
  354. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/values.py +0 -0
  355. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/xls.py +0 -0
  356. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/xlsx.py +0 -0
  357. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/xml.py +0 -0
  358. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/yaml.py +0 -0
  359. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/exporters/zip.py +0 -0
  360. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/format.py +0 -0
  361. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/gui/__init__.py +0 -0
  362. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/gui/base.py +0 -0
  363. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/gui/console.py +0 -0
  364. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/gui/desktop.py +0 -0
  365. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/gui/tui.py +0 -0
  366. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/importers/__init__.py +0 -0
  367. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/importers/base.py +0 -0
  368. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/importers/csv.py +0 -0
  369. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/importers/feather.py +0 -0
  370. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/importers/json.py +0 -0
  371. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/importers/ods.py +0 -0
  372. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/importers/xls.py +0 -0
  373. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/interactive.py +0 -0
  374. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/__init__.py +0 -0
  375. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/_util.py +0 -0
  376. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/cache.py +0 -0
  377. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/code_actions.py +0 -0
  378. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/completion.py +0 -0
  379. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/diagnostics.py +0 -0
  380. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/document.py +0 -0
  381. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/folding.py +0 -0
  382. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/formatting.py +0 -0
  383. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/hover.py +0 -0
  384. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/navigation.py +0 -0
  385. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/rename.py +0 -0
  386. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/lsp/server.py +0 -0
  387. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/manifest.py +0 -0
  388. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/__init__.py +0 -0
  389. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/conditions.py +0 -0
  390. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/control.py +0 -0
  391. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/debug.py +0 -0
  392. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/effects.py +0 -0
  393. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/io.py +0 -0
  394. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/io_export.py +0 -0
  395. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/io_import.py +0 -0
  396. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/prompt.py +0 -0
  397. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/metacommands/upsert.py +0 -0
  398. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/parser.py +0 -0
  399. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/plugins.py +0 -0
  400. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/py.typed +0 -0
  401. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/script/__init__.py +0 -0
  402. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/script/engine.py +0 -0
  403. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/script/variables.py +0 -0
  404. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/state.pyi +0 -0
  405. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/types.py +0 -0
  406. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/__init__.py +0 -0
  407. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/auth.py +0 -0
  408. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/color.py +0 -0
  409. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/crypto.py +0 -0
  410. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/datetime.py +0 -0
  411. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/fileio.py +0 -0
  412. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/gui.py +0 -0
  413. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/mail.py +0 -0
  414. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/numeric.py +0 -0
  415. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/paths.py +0 -0
  416. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/regex.py +0 -0
  417. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/strings.py +0 -0
  418. {execsql2-2.34.0 → execsql2-2.37.0}/src/execsql/utils/timer.py +0 -0
  419. {execsql2-2.34.0 → execsql2-2.37.0}/templates/README.md +0 -0
  420. {execsql2-2.34.0 → execsql2-2.37.0}/templates/config_settings.sqlite +0 -0
  421. {execsql2-2.34.0 → execsql2-2.37.0}/templates/example_config_prompt.sql +0 -0
  422. {execsql2-2.34.0 → execsql2-2.37.0}/templates/make_config_db.sql +0 -0
  423. {execsql2-2.34.0 → execsql2-2.37.0}/templates/md_compare.sql +0 -0
  424. {execsql2-2.34.0 → execsql2-2.37.0}/templates/md_glossary.sql +0 -0
  425. {execsql2-2.34.0 → execsql2-2.37.0}/templates/md_upsert.sql +0 -0
  426. {execsql2-2.34.0 → execsql2-2.37.0}/templates/pg_compare.sql +0 -0
  427. {execsql2-2.34.0 → execsql2-2.37.0}/templates/pg_glossary.sql +0 -0
  428. {execsql2-2.34.0 → execsql2-2.37.0}/templates/script_template.sql +0 -0
  429. {execsql2-2.34.0 → execsql2-2.37.0}/templates/ss_compare.sql +0 -0
  430. {execsql2-2.34.0 → execsql2-2.37.0}/templates/ss_glossary.sql +0 -0
  431. {execsql2-2.34.0 → execsql2-2.37.0}/templates/ss_upsert.sql +0 -0
  432. {execsql2-2.34.0 → execsql2-2.37.0}/tests/__init__.py +0 -0
  433. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/__init__.py +0 -0
  434. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_cli.py +0 -0
  435. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_cli_run.py +0 -0
  436. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_cli_surface.py +0 -0
  437. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_commands.py +0 -0
  438. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_config_validate.py +0 -0
  439. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_dispatch.py +0 -0
  440. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_error_location.py +0 -0
  441. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_init.py +0 -0
  442. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_lint_fixtures.py +0 -0
  443. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_log_exit_record.py +0 -0
  444. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_ping.py +0 -0
  445. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_profile.py +0 -0
  446. {execsql2-2.34.0 → execsql2-2.37.0}/tests/cli/test_undeclared_imports.py +0 -0
  447. {execsql2-2.34.0/tests/db → execsql2-2.37.0/tests/corpus}/__init__.py +0 -0
  448. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/existing_table_loads/changes.json +0 -0
  449. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/existing_table_loads/duckdb.json +0 -0
  450. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/existing_table_loads/mysql.json +0 -0
  451. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/existing_table_loads/mysql_files.json +0 -0
  452. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/existing_table_loads/postgres.json +0 -0
  453. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/existing_table_loads/postgres_files.json +0 -0
  454. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/existing_table_loads/sqlite.json +0 -0
  455. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/existing_table_loads/sqlserver.json +0 -0
  456. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/formatter_shapes/comment_anchoring.sql +0 -0
  457. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/formatter_shapes/escapes_and_literals.sql +0 -0
  458. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/formatter_shapes/substitution_and_metacommands.sql +0 -0
  459. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/formatter_shapes/unparsable_sql.sql +0 -0
  460. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/lint/conditions_and_blocks.sql +0 -0
  461. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/lint/does_not_parse.sql +0 -0
  462. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/lint/invalid.sql +0 -0
  463. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/ods/libreoffice.fods +0 -0
  464. {execsql2-2.34.0 → execsql2-2.37.0}/tests/data/ods/libreoffice.ods +0 -0
  465. {execsql2-2.34.0/tests/exporters → execsql2-2.37.0/tests/db}/__init__.py +0 -0
  466. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/conftest.py +0 -0
  467. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_access_windows.py +0 -0
  468. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_base.py +0 -0
  469. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_bulk_inserts.py +0 -0
  470. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_copy_new.py +0 -0
  471. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_db_adapters_mocked.py +0 -0
  472. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_db_adapters_mocked_extra.py +0 -0
  473. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_dsn.py +0 -0
  474. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_duckdb.py +0 -0
  475. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_existing_table_loads.py +0 -0
  476. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_factory.py +0 -0
  477. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_factory_postgres_encoding.py +0 -0
  478. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_import_atomic.py +0 -0
  479. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_import_replacement_quoted.py +0 -0
  480. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_import_short_rows.py +0 -0
  481. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_import_timezones.py +0 -0
  482. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_mysql_case_folding.py +0 -0
  483. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_mysql_inprocess.py +0 -0
  484. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_mysql_trailing_blank_lines.py +0 -0
  485. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_new_table_checks.py +0 -0
  486. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_odbc_fresh_sessions.py +0 -0
  487. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_oracle_driver.py +0 -0
  488. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_postgres.py +0 -0
  489. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_postgres_inprocess.py +0 -0
  490. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_quoted_substitution_roundtrip.py +0 -0
  491. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_replacement_missing_table.py +0 -0
  492. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_roundtrip_adapters.py +0 -0
  493. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_sqlite.py +0 -0
  494. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_sqlite_extra.py +0 -0
  495. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_sqlserver_driver18.py +0 -0
  496. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_sqlserver_inprocess.py +0 -0
  497. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_target_types.py +0 -0
  498. {execsql2-2.34.0 → execsql2-2.37.0}/tests/db/test_tiers.py +0 -0
  499. {execsql2-2.34.0/tests/gui → execsql2-2.37.0/tests/exporters}/__init__.py +0 -0
  500. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/conftest.py +0 -0
  501. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_base.py +0 -0
  502. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_db.py +0 -0
  503. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_delimited.py +0 -0
  504. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_duckdb_exporter.py +0 -0
  505. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_exporters.py +0 -0
  506. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_feather.py +0 -0
  507. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_html_extended.py +0 -0
  508. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_html_latex.py +0 -0
  509. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_json.py +0 -0
  510. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_json_extended.py +0 -0
  511. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_jsonl.py +0 -0
  512. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_latex_extended.py +0 -0
  513. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_markdown.py +0 -0
  514. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_ods.py +0 -0
  515. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_ods_export.py +0 -0
  516. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_parquet.py +0 -0
  517. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_pretty_extended.py +0 -0
  518. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_raw_extended.py +0 -0
  519. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_columnar.py +0 -0
  520. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_dbfile.py +0 -0
  521. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_delimited.py +0 -0
  522. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_json.py +0 -0
  523. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_latex_xml.py +0 -0
  524. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_markup.py +0 -0
  525. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_ods.py +0 -0
  526. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_pretty_raw.py +0 -0
  527. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_template.py +0 -0
  528. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_values.py +0 -0
  529. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_roundtrip_xlsx.py +0 -0
  530. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_sqlite_exporter.py +0 -0
  531. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_templates.py +0 -0
  532. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_templates_extended.py +0 -0
  533. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_values_extended.py +0 -0
  534. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_values_roundtrip.py +0 -0
  535. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_xls_xlsx.py +0 -0
  536. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_xlsx.py +0 -0
  537. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_xml.py +0 -0
  538. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_yaml.py +0 -0
  539. {execsql2-2.34.0 → execsql2-2.37.0}/tests/exporters/test_zip.py +0 -0
  540. {execsql2-2.34.0/tests/importers → execsql2-2.37.0/tests/gui}/__init__.py +0 -0
  541. {execsql2-2.34.0 → execsql2-2.37.0}/tests/gui/test_backends.py +0 -0
  542. {execsql2-2.34.0 → execsql2-2.37.0}/tests/gui/test_backends_extended.py +0 -0
  543. {execsql2-2.34.0 → execsql2-2.37.0}/tests/gui/test_compare_stats.py +0 -0
  544. {execsql2-2.34.0 → execsql2-2.37.0}/tests/gui/test_compute_row_diffs.py +0 -0
  545. {execsql2-2.34.0 → execsql2-2.37.0}/tests/gui/test_desktop_dialogs.py +0 -0
  546. {execsql2-2.34.0 → execsql2-2.37.0}/tests/gui/test_format_table.py +0 -0
  547. {execsql2-2.34.0 → execsql2-2.37.0}/tests/gui/test_tui_pilot.py +0 -0
  548. {execsql2-2.34.0 → execsql2-2.37.0}/tests/gui/test_tui_pilot_complex.py +0 -0
  549. {execsql2-2.34.0 → execsql2-2.37.0}/tests/gui/test_utils_gui_extended.py +0 -0
  550. {execsql2-2.34.0/tests/integration → execsql2-2.37.0/tests/importers}/__init__.py +0 -0
  551. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/conftest.py +0 -0
  552. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/test_base_extended.py +0 -0
  553. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/test_csv_blank_lines.py +0 -0
  554. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/test_csv_edge_cases.py +0 -0
  555. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/test_csv_importer.py +0 -0
  556. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/test_feather_importer.py +0 -0
  557. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/test_json_importer.py +0 -0
  558. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/test_ods_importer.py +0 -0
  559. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/test_ods_values.py +0 -0
  560. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/test_roundtrip_csv.py +0 -0
  561. {execsql2-2.34.0 → execsql2-2.37.0}/tests/importers/test_xls_importer.py +0 -0
  562. {execsql2-2.34.0/tests/lsp → execsql2-2.37.0/tests/integration}/__init__.py +0 -0
  563. {execsql2-2.34.0 → execsql2-2.37.0}/tests/integration/conftest.py +0 -0
  564. {execsql2-2.34.0 → execsql2-2.37.0}/tests/integration/test_dsn.py +0 -0
  565. {execsql2-2.34.0 → execsql2-2.37.0}/tests/integration/test_duckdb.py +0 -0
  566. {execsql2-2.34.0 → execsql2-2.37.0}/tests/integration/test_mysql.py +0 -0
  567. {execsql2-2.34.0 → execsql2-2.37.0}/tests/integration/test_postgres.py +0 -0
  568. {execsql2-2.34.0 → execsql2-2.37.0}/tests/integration/test_sqlite.py +0 -0
  569. {execsql2-2.34.0 → execsql2-2.37.0}/tests/live_db.py +0 -0
  570. {execsql2-2.34.0/tests/metacommands → execsql2-2.37.0/tests/lsp}/__init__.py +0 -0
  571. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_cache.py +0 -0
  572. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_code_actions.py +0 -0
  573. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_completion.py +0 -0
  574. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_diagnostics.py +0 -0
  575. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_document.py +0 -0
  576. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_folding.py +0 -0
  577. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_formatting.py +0 -0
  578. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_hover.py +0 -0
  579. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_lsp_command.py +0 -0
  580. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_navigation.py +0 -0
  581. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_rename.py +0 -0
  582. {execsql2-2.34.0 → execsql2-2.37.0}/tests/lsp/test_server.py +0 -0
  583. {execsql2-2.34.0/tests/scripts → execsql2-2.37.0/tests/metacommands}/__init__.py +0 -0
  584. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/conftest.py +0 -0
  585. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_assert.py +0 -0
  586. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_breakpoint.py +0 -0
  587. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_conditions_extra.py +0 -0
  588. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_connect.py +0 -0
  589. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_io_export.py +0 -0
  590. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_io_import.py +0 -0
  591. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_connect.py +0 -0
  592. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_data.py +0 -0
  593. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_io_write_extra.py +0 -0
  594. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_metacommands_system_extra.py +0 -0
  595. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_pg_upsert.py +0 -0
  596. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_prompt.py +0 -0
  597. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_row_count.py +0 -0
  598. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_serve_output.py +0 -0
  599. {execsql2-2.34.0 → execsql2-2.37.0}/tests/metacommands/test_show_scripts.py +0 -0
  600. {execsql2-2.34.0/tests/security → execsql2-2.37.0/tests/scripts}/__init__.py +0 -0
  601. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/audit_lint_bad.sql +0 -0
  602. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/audit_smoke/sample.json +0 -0
  603. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/audit_smoke/sample.jsonl +0 -0
  604. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/audit_smoke.sql +0 -0
  605. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/config_runtime.sql +0 -0
  606. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/control_flow.sql +0 -0
  607. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/counters_and_locals.sql +0 -0
  608. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/error_handling.sql +0 -0
  609. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/import_options/has_comments.csv +0 -0
  610. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/import_options.sql +0 -0
  611. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/includes/helper.sql +0 -0
  612. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/includes.sql +0 -0
  613. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/io_formats.sql +0 -0
  614. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/io_roundtrip.sql +0 -0
  615. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/multi_db.sql +0 -0
  616. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/parquet_feather_roundtrip.sql +0 -0
  617. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/parse_only/parse_tree.sql +0 -0
  618. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/predicates.sql +0 -0
  619. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/scripts.sql +0 -0
  620. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/smoke.sql +0 -0
  621. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/subroutine_loops.sql +0 -0
  622. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/subvars_advanced.sql +0 -0
  623. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/template_export/greeting.tmpl +0 -0
  624. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/template_export.sql +0 -0
  625. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/timer.sql +0 -0
  626. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/transactions.sql +0 -0
  627. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/write_create_table.sql +0 -0
  628. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/fixtures/xlsx_ods_roundtrip.sql +0 -0
  629. {execsql2-2.34.0 → execsql2-2.37.0}/tests/scripts/test_sql_scripts.py +0 -0
  630. {execsql2-2.34.0/tests/templates → execsql2-2.37.0/tests/security}/__init__.py +0 -0
  631. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_env_detection.py +0 -0
  632. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_expansion_bomb.py +0 -0
  633. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_import_regex_hardening.py +0 -0
  634. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_log_redaction.py +0 -0
  635. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_network_paths.py +0 -0
  636. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_odbc_connection_strings.py +0 -0
  637. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_odbc_injection.py +0 -0
  638. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_path_containment.py +0 -0
  639. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_substitution_injection.py +0 -0
  640. {execsql2-2.34.0 → execsql2-2.37.0}/tests/security/test_zip_bomb.py +0 -0
  641. {execsql2-2.34.0/tests/utils → execsql2-2.37.0/tests/templates}/__init__.py +0 -0
  642. {execsql2-2.34.0 → execsql2-2.37.0}/tests/templates/conftest.py +0 -0
  643. {execsql2-2.34.0 → execsql2-2.37.0}/tests/templates/test_compare.py +0 -0
  644. {execsql2-2.34.0 → execsql2-2.37.0}/tests/templates/test_glossary.py +0 -0
  645. {execsql2-2.34.0 → execsql2-2.37.0}/tests/templates/test_static.py +0 -0
  646. {execsql2-2.34.0 → execsql2-2.37.0}/tests/templates/test_upsert.py +0 -0
  647. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_api.py +0 -0
  648. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_api_errors.py +0 -0
  649. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_api_extended.py +0 -0
  650. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_api_filewriter.py +0 -0
  651. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_api_isolation.py +0 -0
  652. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_api_subprocess.py +0 -0
  653. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_ast.py +0 -0
  654. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_ast_parser.py +0 -0
  655. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_bundled_templates.py +0 -0
  656. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_config.py +0 -0
  657. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_config_data.py +0 -0
  658. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_config_extended.py +0 -0
  659. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_date_inference.py +0 -0
  660. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_debug_repl.py +0 -0
  661. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_engine.py +0 -0
  662. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_exceptions.py +0 -0
  663. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_format.py +0 -0
  664. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_mail.py +0 -0
  665. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_metacommand_errors.py +0 -0
  666. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_package.py +0 -0
  667. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_parser.py +0 -0
  668. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_parser_params.py +0 -0
  669. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_plugins.py +0 -0
  670. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_reference.py +0 -0
  671. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_registry.py +0 -0
  672. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_release_notes.py +0 -0
  673. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_tooling_versions.py +0 -0
  674. {execsql2-2.34.0 → execsql2-2.37.0}/tests/test_types.py +0 -0
  675. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_auth.py +0 -0
  676. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_auth_extra.py +0 -0
  677. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_crypto.py +0 -0
  678. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_datetime.py +0 -0
  679. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_encodedfile_context.py +0 -0
  680. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_errors.py +0 -0
  681. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_fileio.py +0 -0
  682. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_fileio_extra.py +0 -0
  683. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_keyring_rules.py +0 -0
  684. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_mail_tls.py +0 -0
  685. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_numeric.py +0 -0
  686. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_regex.py +0 -0
  687. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_strings.py +0 -0
  688. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_timer.py +0 -0
  689. {execsql2-2.34.0 → execsql2-2.37.0}/tests/utils/test_timer_extra.py +0 -0
  690. {execsql2-2.34.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,68 @@ ______________________________________________________________________
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
+
62
+ ## [2.35.0] - 2026-10-18
63
+
64
+ ### Added
65
+
66
+ - **`exact_decimals`** (`[input]`) and **`CONFIG EXACT_DECIMALS YES|NO`**: with Yes, `IMPORT` and `COPY … TO NEW` give a column of decimals with different numbers of places an exact `DECIMAL(p,s)` type instead of a floating-point one.
67
+
68
+ ### Changed
69
+
70
+ - **A column of decimals with different numbers of places** (`1.50`, `2`, `-3.25`) gets a floating-point type again when `IMPORT` or `COPY … TO NEW` creates a table (it was `DECIMAL(p,s)` from 2.22.0). A column with a value of more than 15 significant digits stays `DECIMAL(p,s)`, so no digit is lost. Set `exact_decimals` to keep every such column exact.
71
+
72
+ ### Fixed
73
+
74
+ - **The "potential un-substituted variable" warning** is printed only when `write_warnings` is on, to stderr as `**** Warning …`, as documented; it was printed to stdout for every command with an undefined `!!var!!`. It is always written to `execsql.log`.
75
+
76
+ ______________________________________________________________________
77
+
16
78
  ## [2.34.0] - 2026-10-18
17
79
 
18
80
  ### Added
@@ -64,6 +64,19 @@ just test-templates-down # removes the containers
64
64
 
65
65
  SQL Server is included only when an ODBC driver for it is installed. A template bug the tests have found but not yet fixed is marked with `known_bug(...)`, a strict expected failure: the fix makes the test pass, which fails the run until the marker is removed with it.
66
66
 
67
+ ### Script behavior corpus
68
+
69
+ `tests/corpus/` checks that whole scripts do under execsql2 what they did under upstream execsql 1.130.1: the same exit status, console output, files written and table contents. Each case is a directory in `tests/corpus/cases/` holding `script.sql` and the files it reads. Upstream's results are recorded in `tests/corpus/results/`, so the normal test run compares against them without upstream installed. A variable a case checks is `WRITE`n to a file, because upstream has no way to read variables after a run.
70
+
71
+ To add a case, create its directory, then record what upstream does (this installs execsql 1.130.1 from PyPI under Python 3.12 into `~/.cache/execsql-corpus/` on first use):
72
+
73
+ ```bash
74
+ uv run python -m tests.corpus.record my_new_case
75
+ uv run pytest tests/corpus
76
+ ```
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. 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
+
67
80
  ## Building the Docs
68
81
 
69
82
  ```bash
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: execsql2
3
- Version: 2.34.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.34.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.34.0
324
+ rev: v2.37.0
325
325
  hooks:
326
326
  - id: execsql-format
327
327
  - id: execsql-lint
@@ -88,24 +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
- | `show_progress` | `[input]` | Enable Rich progress bar for IMPORT (default: `no`). |
96
- | `import_progress_interval` | `[input]` | Log a status line every N rows during IMPORT (default: `0`). |
97
- | `gui_framework` | `[interface]` | GUI backend: `tkinter` (default) or `textual` (terminal UI). |
98
- | `log_sql` | `[config]` | Enable SQL audit logging (default: `no`). |
99
- | `max_log_size_mb` | `[config]` | Rotate the log file at this size in MB (default: `0` = disabled). |
100
- | `macos_config_file` | `[config]` | Additional config file path, active only on macOS. |
101
- | `allow_rm_file` | `[config]` | Disable the `RM_FILE` metacommand (default: `yes`). Symmetric with `allow_system_cmd`; also `--no-rm-file` on the CLI. |
102
- | `allow_serve` | `[config]` | Disable the `SERVE` metacommand (default: `yes`). Symmetric with `allow_system_cmd`; also `--no-serve` on the CLI. |
103
- | `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. |
104
- | `serve_root` | `[config]` | Path-containment root for `SERVE` (default: none). Same semantics as `include_root`. |
105
- | `template_root` | `[config]` | Path-containment root for Jinja2 / `string.Template` loaders (default: none). Same semantics as `include_root`. |
106
- | `max_substitution_bytes` | `[config]` | Byte ceiling on a single substitution-variable expansion (default: `10485760` = 10 MB) to defeat exponential-expansion bombs. |
107
- | `indent`, `leading_comma`, `sql` | `[format]` | Layout defaults for `execsql format`; a flag on the command line wins. |
108
- | `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`. |
109
110
 
110
111
  ### Tools
111
112
 
@@ -189,7 +190,7 @@ Formatter correctness notes added in the 2.19.x line:
189
190
 
190
191
  ### Debugging { #debugging }
191
192
 
192
- 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).
193
194
 
194
195
  ### Library API
195
196
 
@@ -257,6 +258,7 @@ All 33 mutable runtime globals in `state.py` have been consolidated into a `Runt
257
258
 
258
259
  - **`$HOSTNAME`** — Network name of the machine running execsql (`platform.node()`). Useful for log messages and environment detection.
259
260
  - **`$SYSTEM_CMD_PID`** — New system variable set to the PID of the background process when `SHELL … CONTINUE` is used.
261
+ - **`!'!var!'!` adds the quotes** — `!'!name!'!` becomes a complete string literal: the value is wrapped in single quotes and its apostrophes doubled (`O'Brien` → `'O''Brien'`), so a script writes `where author = !'!name!'!`. Upstream only doubled the apostrophes, so its scripts wrote the quotes themselves (`'!'!name!'!'`); in execsql2 that form has two sets of quotes and fails. Remove the outer quotes when moving such a script.
260
262
  - **Cycle detection** — `substitute_vars()` raises an error after 100 iterations to prevent infinite loops when variables reference each other cyclically. Upstream had no protection.
261
263
  - **O(1) substitution** — Variable substitution uses a single combined regex and dict lookup instead of O(V) per-variable regex passes. Behavior is identical; performance is improved.
262
264
  - **Lazy `$RANDOM`/`$UUID`** — These system variables are now computed on first access rather than generated unconditionally for every statement. Behavior is identical when referenced; scripts that never reference them skip the computation entirely.
@@ -288,7 +290,13 @@ The legacy flat command-list engine (`_parse_script_lines` / `runscripts` / `Com
288
290
 
289
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.
290
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.
291
- - **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.
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
+ - **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).
292
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.
293
301
  - **Instance-scoped script registry** — Named SCRIPT blocks are stored on the `RuntimeContext` instance instead of a module-level dict, preventing cross-execution contamination.
294
302
 
@@ -299,6 +307,7 @@ The legacy flat command-list engine (`_parse_script_lines` / `runscripts` / `Com
299
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>`.
300
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.
301
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).
302
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`.
303
312
 
304
313
  ______________________________________________________________________
@@ -435,6 +444,12 @@ These are behavioral changes driven by security or correctness issues in the ups
435
444
  | DuckDB float columns were single precision | `dbt_duckdb` mapped `DT_Float` to `REAL`. `DT_Float` is documented as IEEE double precision and a Python float always is one, so every float written to DuckDB was narrowed: `1234.567` was stored and returned as `1234.5670166015625`. PostgreSQL, SQLite, SQL Server, MySQL, Access, Firebird and DSN all map `DT_Float` to a double; DuckDB was the only backend that did not, and is now `DOUBLE`. |
436
445
  | VALUES export wrote dates and timestamps unquoted | The literal renderer quoted `str` and emitted `NULL` for `None`, but sent everything else through `str()` bare. A `date` became `2026-09-24` in the generated `INSERT`, which is not a syntax error — it is a valid SQL expression evaluating to 1993, so PostgreSQL inserted that and reported nothing. A `timestamp` contains a space and failed outright. Quoting is now the default and only numbers are emitted bare, so a type the renderer has not been taught about is safe rather than silently wrong. |
437
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. |
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. |
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. |
438
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. |
439
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. |
440
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. |
@@ -446,6 +461,7 @@ These are behavioral changes driven by security or correctness issues in the ups
446
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. |
447
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. |
448
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). |
449
465
 
450
466
  ______________________________________________________________________
451
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.34.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
@@ -141,6 +141,10 @@ The section and property names that may be used in a configuration file are list
141
141
 
142
142
  : Determines whether empty strings in the input are preserved or, alternatively, will be replaced by NULL. The property value should be either "Yes" or "No". The default, "Yes", indicates that empty strings are allowed. A value of "No" will cause all empty strings to be replaced by NULL. When this is set to "No", a string value consisting of a sequence of zero or more space characters will be considered to be an empty string. There is no command-line option corresponding to this configuration parameter, but the metacommand [CONFIG EMPTY_STRINGS](metacommands.md#empty_strings) can also be used to change this configuration item.
143
143
 
144
+ `exact_decimals`
145
+
146
+ : Determines the data type of a column of decimal numbers with different numbers of decimal places, such as `1.50`, `2` and `-3.25`, when the [IMPORT](metacommands.md#import) or [COPY](metacommands.md#copy) metacommand creates a table. The default, "No", gives such a column a floating-point type (`double precision` on PostgreSQL, `double` on MySQL and DuckDB, `float` on SQL Server), unless a value has more than 15 significant digits, which a floating-point column cannot hold exactly: then the column is an exact decimal, so no digit is lost. "Yes" always gives such a column an exact decimal type wide enough for every value (`numeric(3,2)` for those values), for values such as money amounts that should be stored and compared exactly. A column whose values all have the same number of decimal places is an exact decimal either way. The metacommand [CONFIG EXACT_DECIMALS](metacommands.md#exact_decimals) can also be used to change this configuration item.
147
+
144
148
  `fold_column_headers` { #setting_fold_column_headers }
145
149
 
146
150
  : Whether or not to fold (convert) the case of all column headers to lowercase or uppercase, or to leave them unchanged when data are [IMPORTed](metacommands.md#import). Valid values are "No" (the default), "Lower", and "Upper". Case does not matter in the specification.
@@ -372,7 +376,7 @@ The section and property names that may be used in a configuration file are list
372
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.
373
377
 
374
378
  `system_cmd_timeout` { #system_cmd_timeout }
375
- : 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.
376
380
 
377
381
  `allow_rm_file` { #allow_rm_file }
378
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`.
@@ -381,13 +385,13 @@ The section and property names that may be used in a configuration file are list
381
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`.
382
386
 
383
387
  `include_root` { #include_root }
384
- : 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.
385
389
 
386
390
  `serve_root` { #serve_root }
387
- : 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.
388
392
 
389
393
  `template_root` { #template_root }
390
- : 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.
391
395
 
392
396
  `max_substitution_bytes` { #max_substitution_bytes }
393
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.34.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 }