execsql2 2.16.2__py3-none-any.whl → 2.16.4__py3-none-any.whl

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 (23) hide show
  1. execsql/script/executor.py +34 -0
  2. execsql/script/parser.py +1 -1
  3. {execsql2-2.16.2.dist-info → execsql2-2.16.4.dist-info}/METADATA +1 -1
  4. {execsql2-2.16.2.dist-info → execsql2-2.16.4.dist-info}/RECORD +23 -23
  5. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/README.md +0 -0
  6. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/config_settings.sqlite +0 -0
  7. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
  8. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/execsql.conf +0 -0
  9. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/make_config_db.sql +0 -0
  10. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/md_compare.sql +0 -0
  11. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/md_glossary.sql +0 -0
  12. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/md_upsert.sql +0 -0
  13. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/pg_compare.sql +0 -0
  14. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/pg_glossary.sql +0 -0
  15. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/pg_upsert.sql +0 -0
  16. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/script_template.sql +0 -0
  17. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/ss_compare.sql +0 -0
  18. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/ss_glossary.sql +0 -0
  19. {execsql2-2.16.2.data → execsql2-2.16.4.data}/data/execsql2_extras/ss_upsert.sql +0 -0
  20. {execsql2-2.16.2.dist-info → execsql2-2.16.4.dist-info}/WHEEL +0 -0
  21. {execsql2-2.16.2.dist-info → execsql2-2.16.4.dist-info}/entry_points.txt +0 -0
  22. {execsql2-2.16.2.dist-info → execsql2-2.16.4.dist-info}/licenses/LICENSE.txt +0 -0
  23. {execsql2-2.16.2.dist-info → execsql2-2.16.4.dist-info}/licenses/NOTICE +0 -0
@@ -448,6 +448,33 @@ def _execute_batch(
448
448
  ctx.status.batch.end_batch()
449
449
 
450
450
 
451
+ def _pre_register_scripts(ctx: RuntimeContext, nodes: list[Node]) -> None:
452
+ """Pre-scan AST nodes and register all ScriptBlock definitions.
453
+
454
+ The legacy engine used a two-pass approach — parse first (registering all
455
+ BEGIN SCRIPT blocks), then execute. The AST executor walks the tree in a
456
+ single pass, so forward references (EXECUTE SCRIPT before BEGIN SCRIPT)
457
+ would fail. This pre-scan restores compatibility by registering all script
458
+ blocks before execution begins.
459
+
460
+ Only scans the top level and inside IF/ELSE blocks — SCRIPT blocks inside
461
+ LOOPs or other SCRIPTs are not pre-registered (matching legacy behavior
462
+ where nested definitions weren't visible until the enclosing block ran).
463
+ """
464
+ for node in nodes:
465
+ if isinstance(node, ScriptBlock):
466
+ _register_script_block(ctx, node)
467
+ elif isinstance(node, IfBlock):
468
+ # Scripts defined inside IF branches should be registered too,
469
+ # since the legacy parser registered them unconditionally at
470
+ # parse time regardless of the IF condition.
471
+ _pre_register_scripts(ctx, node.body)
472
+ for clause in node.elseif_clauses:
473
+ _pre_register_scripts(ctx, clause.body)
474
+ if node.else_body:
475
+ _pre_register_scripts(ctx, node.else_body)
476
+
477
+
451
478
  def _register_script_block(ctx: RuntimeContext, node: ScriptBlock) -> None:
452
479
  """Register a named SCRIPT block.
453
480
 
@@ -799,6 +826,9 @@ def _execute_include_native(
799
826
  encoding = ctx.conf.script_encoding if ctx.conf else "utf-8"
800
827
  included_tree = parse_script(target, encoding=encoding)
801
828
 
829
+ # Pre-register SCRIPT blocks in the included file so forward references work.
830
+ _pre_register_scripts(ctx, included_tree.body)
831
+
802
832
  # Execute with include-chain tracking
803
833
  ctx.include_chain.append(resolved)
804
834
  try:
@@ -915,6 +945,10 @@ def execute(script: Script, *, ctx: RuntimeContext | None = None) -> None:
915
945
  except (OSError, ValueError):
916
946
  ctx.include_chain.append(script.source)
917
947
  set_static_system_vars(ctx)
948
+ # Pre-register all SCRIPT blocks so forward references work.
949
+ # The legacy engine registered scripts at parse time (two-pass);
950
+ # the AST executor must do an explicit pre-scan.
951
+ _pre_register_scripts(ctx, script.body)
918
952
  # Push a root frame so commandliststack is never empty during AST
919
953
  # execution. This ensures get_subvarset(), current_script_line(),
920
954
  # xf_sub_defined(), the REPL, and all other commandliststack readers
execsql/script/parser.py CHANGED
@@ -60,7 +60,7 @@ __all__ = [
60
60
  # ---------------------------------------------------------------------------
61
61
 
62
62
  _BEGIN_SCRIPT_RX = re.compile(
63
- r"^\s*(?:BEGIN|CREATE)\s+SCRIPT\s+(?P<name>\w+)(?P<paramexpr>\s+.+)?$",
63
+ r"^\s*(?:BEGIN|CREATE)\s+SCRIPT\s+(?P<name>\w+)(?P<paramexpr>\s*.+)?$",
64
64
  re.I,
65
65
  )
66
66
  _END_SCRIPT_RX = re.compile(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: execsql2
3
- Version: 2.16.2
3
+ Version: 2.16.4
4
4
  Summary: Runs a SQL script against a PostgreSQL, SQLite, MariaDB/MySQL, DuckDB, Firebird, MS-Access, MS-SQL-Server, or Oracle database, or an ODBC DSN. Provides metacommands to import and export data, copy data between databases, conditionally execute SQL and metacommands, and dynamically alter SQL and metacommands with substitution variables.
5
5
  Project-URL: Homepage, https://execsql2.readthedocs.io
6
6
  Project-URL: Repository, https://github.com/geocoug/execsql
@@ -84,8 +84,8 @@ execsql/script/__init__.py,sha256=3WaBklMVIWjtCsYQ-BVo9UAVEIATOgeGsuyv21YKnxo,39
84
84
  execsql/script/ast.py,sha256=yFw9ZvLLDNNSmSgy7cwK2fXLatpp2CKYAAyOneJoKVc,18836
85
85
  execsql/script/control.py,sha256=s-1eZdGARM6H1FwZ6VDdO_f50j7bvvRtTHesfUm9tbc,6144
86
86
  execsql/script/engine.py,sha256=EhuVBniOrFkzAW4I3NIZLt3INHTZJvlYoF7B99rZBLI,29391
87
- execsql/script/executor.py,sha256=35RGyua8sGR2rrrnf3WvaC3nAjobKoH9pmVm4FJ5oZY,34213
88
- execsql/script/parser.py,sha256=4Mk5tF4rr9lpJpJh-cPPFemkQta2QBbNnMqFQ6S5huo,24983
87
+ execsql/script/executor.py,sha256=YbvoviWeUv9dcT-FWtAY4IsvhC9d6MvtHRtTNXkZL4s,35931
88
+ execsql/script/parser.py,sha256=nAyLaDP-nL6C-chvlaSu0Oqh8ACcCCZjFacv0Fhyp58,24983
89
89
  execsql/script/variables.py,sha256=ZSBGQUsoii6w3dLDVY9xxoPIV6wY0sAV_BNIQ6pgQAE,14328
90
90
  execsql/utils/__init__.py,sha256=0uR6JwVJQRX3vceByNBduCAf5dd5assKjeqJUWvpZoA,278
91
91
  execsql/utils/auth.py,sha256=onXzNkNZQZxGC5w7eey06sjvAIAX_Lf9g7nUJtcsel0,7009
@@ -99,24 +99,24 @@ execsql/utils/numeric.py,sha256=xh02ANSRk3nUpQ-rtm66ILoMqoi7HtzCoRMIOT9U8QI,1570
99
99
  execsql/utils/regex.py,sha256=diEzTZqU_HHwVMadPAvN1Vgzhl7I03eVaEFGCXyGGL8,3770
100
100
  execsql/utils/strings.py,sha256=5Dvzrk-9SIw2lpxXZQkiJbNyo1sy7iXXAtSULlZ0KG8,8488
101
101
  execsql/utils/timer.py,sha256=eDYf5VzCNFk7oo90InJucUm3XcBdhYMogjZMqeg9xzc,1899
102
- execsql2-2.16.2.data/data/execsql2_extras/README.md,sha256=sxwVyU0ZahCfANv56LahkyuM505kFjrMhe-1SvWE69E,4845
103
- execsql2-2.16.2.data/data/execsql2_extras/config_settings.sqlite,sha256=aY5cxR7Q7J6zJ4bC9lu5mHUrhy211Cq3MNKPQVCt02E,20480
104
- execsql2-2.16.2.data/data/execsql2_extras/example_config_prompt.sql,sha256=SY3Jxn1qcVm4kPW9xmmTfknHfvURXmeEYTbRjYrjGSw,7487
105
- execsql2-2.16.2.data/data/execsql2_extras/execsql.conf,sha256=_45iJ-KWZnB8uMW_gEg067MM5pmGJ-dVl7VbAZMunAE,9530
106
- execsql2-2.16.2.data/data/execsql2_extras/make_config_db.sql,sha256=WwyC6dK-Eh5CAVppiBCDHqiI1_wEI9U95Ytpr4lsZkg,8726
107
- execsql2-2.16.2.data/data/execsql2_extras/md_compare.sql,sha256=B8Wd7LZ0vnMY2qvA139JIEBkPObgRH2i5xj6PejTQt8,24092
108
- execsql2-2.16.2.data/data/execsql2_extras/md_glossary.sql,sha256=DJRHcU5NbFpxTTX-IwH3yRlsboj1q6BBGrUAHKn4Cuo,10796
109
- execsql2-2.16.2.data/data/execsql2_extras/md_upsert.sql,sha256=v_7GbWh_N1mBTmw3gvTrkagOVp2q0KmXvM8hE-DlFxY,112524
110
- execsql2-2.16.2.data/data/execsql2_extras/pg_compare.sql,sha256=9dWa8hnfy5dVJI-z2iGpd9JzQmI4j2ziMlEdpnr66ro,24352
111
- execsql2-2.16.2.data/data/execsql2_extras/pg_glossary.sql,sha256=pKjIIDsROAgJq2H-1qNEcRMAWManivcZ_AEVHzUUlic,9908
112
- execsql2-2.16.2.data/data/execsql2_extras/pg_upsert.sql,sha256=k7AFiGTLBy3nf-qO5QIaZrEYTAKvdxxU3JDLx9jqkzs,108315
113
- execsql2-2.16.2.data/data/execsql2_extras/script_template.sql,sha256=1Estacb_vm1FgK41k_G9nuduP1yiA-fQ1Kn4Z4mv5Ao,11153
114
- execsql2-2.16.2.data/data/execsql2_extras/ss_compare.sql,sha256=TsVxWm3cEpR5-EiMYXNhtaY0arSNeKZhsJdHdLA7xeI,24833
115
- execsql2-2.16.2.data/data/execsql2_extras/ss_glossary.sql,sha256=cLM7nN8JOIu9ZVP9oY9qdSK3hrnWJiDcX6nZmQQbQWI,13065
116
- execsql2-2.16.2.data/data/execsql2_extras/ss_upsert.sql,sha256=BCqmBykXBF-BpCgOFeG1qhf2XfScKsxPD17wd1hYfHw,120647
117
- execsql2-2.16.2.dist-info/METADATA,sha256=zFrU6GFUFGmxMEW3tV0Hh1Zl2IaU2WCxFfsFBIGW0Fo,20920
118
- execsql2-2.16.2.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
119
- execsql2-2.16.2.dist-info/entry_points.txt,sha256=sUOxkM-dN1eBGGpSpDLsAaE0yNXYQKWZAfxPOlMkQyk,90
120
- execsql2-2.16.2.dist-info/licenses/LICENSE.txt,sha256=LBdhuxejF8_bLCHZ2kWfmDXpDGUu914Gbd6_3JjCRe0,676
121
- execsql2-2.16.2.dist-info/licenses/NOTICE,sha256=sqVrM73Ys9zfvWC_P797lHfTnoPW_ETeBSrUTFaob0A,339
122
- execsql2-2.16.2.dist-info/RECORD,,
102
+ execsql2-2.16.4.data/data/execsql2_extras/README.md,sha256=sxwVyU0ZahCfANv56LahkyuM505kFjrMhe-1SvWE69E,4845
103
+ execsql2-2.16.4.data/data/execsql2_extras/config_settings.sqlite,sha256=aY5cxR7Q7J6zJ4bC9lu5mHUrhy211Cq3MNKPQVCt02E,20480
104
+ execsql2-2.16.4.data/data/execsql2_extras/example_config_prompt.sql,sha256=SY3Jxn1qcVm4kPW9xmmTfknHfvURXmeEYTbRjYrjGSw,7487
105
+ execsql2-2.16.4.data/data/execsql2_extras/execsql.conf,sha256=_45iJ-KWZnB8uMW_gEg067MM5pmGJ-dVl7VbAZMunAE,9530
106
+ execsql2-2.16.4.data/data/execsql2_extras/make_config_db.sql,sha256=WwyC6dK-Eh5CAVppiBCDHqiI1_wEI9U95Ytpr4lsZkg,8726
107
+ execsql2-2.16.4.data/data/execsql2_extras/md_compare.sql,sha256=B8Wd7LZ0vnMY2qvA139JIEBkPObgRH2i5xj6PejTQt8,24092
108
+ execsql2-2.16.4.data/data/execsql2_extras/md_glossary.sql,sha256=DJRHcU5NbFpxTTX-IwH3yRlsboj1q6BBGrUAHKn4Cuo,10796
109
+ execsql2-2.16.4.data/data/execsql2_extras/md_upsert.sql,sha256=v_7GbWh_N1mBTmw3gvTrkagOVp2q0KmXvM8hE-DlFxY,112524
110
+ execsql2-2.16.4.data/data/execsql2_extras/pg_compare.sql,sha256=9dWa8hnfy5dVJI-z2iGpd9JzQmI4j2ziMlEdpnr66ro,24352
111
+ execsql2-2.16.4.data/data/execsql2_extras/pg_glossary.sql,sha256=pKjIIDsROAgJq2H-1qNEcRMAWManivcZ_AEVHzUUlic,9908
112
+ execsql2-2.16.4.data/data/execsql2_extras/pg_upsert.sql,sha256=k7AFiGTLBy3nf-qO5QIaZrEYTAKvdxxU3JDLx9jqkzs,108315
113
+ execsql2-2.16.4.data/data/execsql2_extras/script_template.sql,sha256=1Estacb_vm1FgK41k_G9nuduP1yiA-fQ1Kn4Z4mv5Ao,11153
114
+ execsql2-2.16.4.data/data/execsql2_extras/ss_compare.sql,sha256=TsVxWm3cEpR5-EiMYXNhtaY0arSNeKZhsJdHdLA7xeI,24833
115
+ execsql2-2.16.4.data/data/execsql2_extras/ss_glossary.sql,sha256=cLM7nN8JOIu9ZVP9oY9qdSK3hrnWJiDcX6nZmQQbQWI,13065
116
+ execsql2-2.16.4.data/data/execsql2_extras/ss_upsert.sql,sha256=BCqmBykXBF-BpCgOFeG1qhf2XfScKsxPD17wd1hYfHw,120647
117
+ execsql2-2.16.4.dist-info/METADATA,sha256=ZYwrqqyJQr9wriwp4uY0Jq5ruu8ysBy-pk6k_X_iJMM,20920
118
+ execsql2-2.16.4.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
119
+ execsql2-2.16.4.dist-info/entry_points.txt,sha256=sUOxkM-dN1eBGGpSpDLsAaE0yNXYQKWZAfxPOlMkQyk,90
120
+ execsql2-2.16.4.dist-info/licenses/LICENSE.txt,sha256=LBdhuxejF8_bLCHZ2kWfmDXpDGUu914Gbd6_3JjCRe0,676
121
+ execsql2-2.16.4.dist-info/licenses/NOTICE,sha256=sqVrM73Ys9zfvWC_P797lHfTnoPW_ETeBSrUTFaob0A,339
122
+ execsql2-2.16.4.dist-info/RECORD,,