Files
cobol-java-v3/tests/cobol_testgen/test_to_sql_schema_table.py
T

136 lines
5.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
r"""DB2 schema 限定表名(SCHEMA.TABLE)在数据生成层的归一化测试。
根因:`FROM SALARYDB.EMP-MASTER` 中 `SALARYDB.` 限定符使 core.py 表名正则
`(\w[\w-]*)` 遇 `.` 即停,把种子表解析为 `SALARYDB`build_db_input 把 24 条
EMP 种子行挂到不存在的 `SALARYDB` 表键下,插入时被丢弃 → EMP_MASTER 未播种,
运行时 EMP 正常路径(SEARCH/EVALUATE)无法覆盖。
修复(分层,通用):
- core.py `_parse_sql` 各表名正则捕获完整限定名(SCHEMA.TABLE 不丢失)。
- to_sql.py `collect_sql_meta` 用 `_norm_table` 剥掉限定符取末段(EMP-MASTER),
与 YAML schema 表名一致;种子键归一,`_populate_database` 正常插入。
"""
import sys, os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
from cobol_testgen.core import extract_sql_assignments
from cobol_testgen.to_sql import collect_sql_meta, build_db_input
_SRC_DECLARE = (
" PROCEDURE DIVISION.\n"
" EXEC SQL\n"
" DECLARE C2 CURSOR FOR\n"
" SELECT EMP-ID, EMP-NAME, DEPT-CODE, BASE-SALARY\n"
" FROM SALARYDB.EMP-MASTER\n"
" ORDER BY EMP-ID\n"
" END-EXEC.\n"
)
def test_extract_sql_assignments_keeps_full_qualified_table():
"""core.py 表名正则须捕获完整限定名(不丢失 .EMP-MASTER)。"""
assignments = extract_sql_assignments(_SRC_DECLARE)
tables = [a.get("table") for a in assignments.values() for a in a]
assert "SALARYDB.EMP-MASTER" in tables, f"qualified table lost: {tables}"
def test_collect_sql_meta_normalizes_schema_qualified_table():
"""collect_sql_meta 把 SCHEMA.TABLE 归一化为末段表名。"""
assignments = {
"__SQL_CURSOR_C2": [{
"type": "exec_sql_select",
"table": "SALARYDB.EMP-MASTER",
"select_list": "EMP-ID, EMP-NAME, DEPT-CODE, BASE-SALARY",
"into_vars": ["DBV-EMP-ID", "DBV-EMP-NAME", "DBV-DEPT-CODE", "DBV-BASE-SALARY"],
"where": "",
"sql_text": "DECLARE C2 CURSOR FOR SELECT EMP-ID FROM SALARYDB.EMP-MASTER",
}],
}
declared = {"EMP-MASTER": [
{"name": "EMP-ID", "db_type": "CHAR", "size": 8},
{"name": "EMP-NAME", "db_type": "CHAR", "size": 40},
{"name": "DEPT-CODE", "db_type": "CHAR", "size": 2},
{"name": "BASE-SALARY", "db_type": "CHAR", "size": 9},
]}
sql_meta = collect_sql_meta(assignments, declared)
assert len(sql_meta) == 1
assert sql_meta[0]["table"] == "EMP-MASTER", sql_meta[0]["table"]
def test_build_db_input_seeds_emp_master_not_salarydb():
"""种子行键必须是 EMP-MASTER(而非 SALARYDB),否则插入时被丢弃。"""
branch_paths = [
([('SQLCODE', '=', '0', True)], {}),
]
records = [{
"DBV-EMP-ID": "A0000001",
"DBV-EMP-NAME": "TANAKA",
"DBV-DEPT-CODE": "01",
"DBV-BASE-SALARY": "429010",
}]
declared = {"EMP-MASTER": [
{"name": "EMP-ID", "db_type": "CHAR", "size": 8},
{"name": "EMP-NAME", "db_type": "CHAR", "size": 40},
{"name": "DEPT-CODE", "db_type": "CHAR", "size": 2},
{"name": "BASE-SALARY", "db_type": "CHAR", "size": 9},
]}
assignments = {
"__SQL_CURSOR_C2": [{
"type": "exec_sql_select",
"table": "SALARYDB.EMP-MASTER",
"select_list": "EMP-ID, EMP-NAME, DEPT-CODE, BASE-SALARY",
"into_vars": ["DBV-EMP-ID", "DBV-EMP-NAME", "DBV-DEPT-CODE", "DBV-BASE-SALARY"],
"where": "",
"sql_text": "DECLARE C2 CURSOR FOR SELECT EMP-ID FROM SALARYDB.EMP-MASTER",
}],
}
db_input = build_db_input(
branch_paths, [], assignments,
collect_sql_meta(assignments, declared),
declared,
records=records,
)
assert "SALARYDB" not in db_input, f"wrong table key: {list(db_input.keys())}"
assert "EMP-MASTER" in db_input, f"missing EMP-MASTER key: {list(db_input.keys())}"
def test_select_where_accept_fed_hostvar_uses_runtime_default():
"""WHERE 宿主变量由 ACCEPT FROM COMMAND-LINE 馈入时,种子必须用运行时
缺省值(如 SHA02MNC RATES 的 WRK-YEAR-MONTH='202605'),而非记录里的
合成值('I00001')。否则 EFFECTIVE-FROM/TO 不满足 WHERERATES 不装载,
SEARCH/EVALUATE 无法覆盖。"""
branch_paths = [
([('SQLCODE', '=', '0', True)], {}),
]
records = [{"WRK-YEAR-MONTH": "I00001"}]
assignments = {
"WRK-YEAR-MONTH": [
{"type": "accept", "from": "COMMAND-LINE"},
{"type": "move_literal", "literal": "202605"},
],
}
sql_meta = [{
"type": "exec_sql_select",
"table": "INSURANCE-RATES",
"select_list": "EFFECTIVE-FROM, EFFECTIVE-TO",
"into_vars": [],
"where": "EFFECTIVE-FROM <= :WRK-YEAR-MONTH AND EFFECTIVE-TO >= :WRK-YEAR-MONTH",
"where_constraints": [
{"col": "EFFECTIVE-FROM", "type": "host_var", "host_var": "WRK-YEAR-MONTH", "op": "<="},
{"col": "EFFECTIVE-TO", "type": "host_var", "host_var": "WRK-YEAR-MONTH", "op": ">="},
],
}]
declared = {"INSURANCE-RATES": [
{"name": "EFFECTIVE-FROM", "db_type": "CHAR", "size": 6},
{"name": "EFFECTIVE-TO", "db_type": "CHAR", "size": 6},
]}
db_input = build_db_input(
branch_paths, [], assignments, sql_meta, declared, records=records,
)
rows = db_input.get("INSURANCE-RATES", [])
assert rows, "no INSURANCE-RATES seed rows"
assert rows[0]["EFFECTIVE-FROM"].strip() == "202605", (
f"seed EFFECTIVE-FROM={rows[0]['EFFECTIVE-FROM']!r} not runtime default"
)
assert rows[0]["EFFECTIVE-TO"].strip() == "202605"