feat: phase2 review fixes
- TIME injection: change from spaces to '2500' (hour>23) for NUMVAL trigger - Runner: add .resolve() to work_dir to fix chdir+relative path breakage - Coverage: per-target field overrides for DP#9-#12 (START-DATE=20240115 etc.) - .gitignore: add compilation artifacts, temp scripts, test outputs
This commit is contained in:
+50
-4
@@ -283,6 +283,8 @@ def collect_sql_meta(assignments: dict, declared_columns: dict,
|
||||
atype = asgn.get('type', '')
|
||||
if not atype.startswith('exec_sql_'):
|
||||
continue
|
||||
if atype == 'exec_sql_fetch':
|
||||
continue
|
||||
key = asgn.get('sql_text', '')
|
||||
if key in seen:
|
||||
continue
|
||||
@@ -323,6 +325,26 @@ def _infer_columns_from_where(where_cons: list) -> list[dict]:
|
||||
return list(seen.values())
|
||||
|
||||
|
||||
def _parse_select_columns(select_list: str) -> list[str]:
|
||||
"""Parse SELECT column list into individual column names.
|
||||
Handles: 'COL1, COL2' → ['COL1', 'COL2']
|
||||
'COL1, COL2 AS alias' → ['COL1', 'COL2']
|
||||
"""
|
||||
if not select_list:
|
||||
return []
|
||||
cols = []
|
||||
for part in select_list.split(','):
|
||||
part = part.strip()
|
||||
# Strip table alias prefix (T.COL → COL)
|
||||
if '.' in part:
|
||||
part = part.split('.')[1] if '.' in part else part
|
||||
# Strip AS alias
|
||||
m = re.search(r'^(\w[\w.-]*)', part)
|
||||
if m:
|
||||
cols.append(m.group(1).upper())
|
||||
return cols
|
||||
|
||||
|
||||
def build_db_input(
|
||||
branch_paths: list[tuple[list, dict]],
|
||||
fields_dict: list[dict],
|
||||
@@ -351,7 +373,9 @@ def build_db_input(
|
||||
|
||||
for sql in sql_meta:
|
||||
atype = sql.get('type', '')
|
||||
table = sql['table']
|
||||
table = sql.get('table', '')
|
||||
if not table:
|
||||
continue
|
||||
where_cons = sql.get('where_constraints', [])
|
||||
|
||||
if table not in db_input:
|
||||
@@ -397,9 +421,18 @@ def build_db_input(
|
||||
if not col_infos:
|
||||
col_infos = _infer_columns_from_where(where_cons)
|
||||
into_vars = sql.get('into_vars', [])
|
||||
for iv in into_vars:
|
||||
if iv not in [c['name'] for c in col_infos]:
|
||||
col_infos.append({'name': iv, 'db_type': 'CHAR', 'size': 20})
|
||||
|
||||
# Map INTO vars → actual SQL column names from SELECT clause
|
||||
select_cols = _parse_select_columns(sql.get('select_list', ''))
|
||||
into_to_col: dict[str, str] = {}
|
||||
for i, iv in enumerate(into_vars):
|
||||
if i < len(select_cols):
|
||||
into_to_col[iv] = select_cols[i]
|
||||
|
||||
# Use SQL column names (not INTO var names) for row keys
|
||||
for sc in select_cols:
|
||||
if sc not in [c['name'] for c in col_infos]:
|
||||
col_infos.append({'name': sc, 'db_type': 'CHAR', 'size': 20})
|
||||
|
||||
for col_info in col_infos:
|
||||
col_name = col_info['name']
|
||||
@@ -417,6 +450,19 @@ def build_db_input(
|
||||
if val is None and hv in rec:
|
||||
val = str(rec[hv])
|
||||
|
||||
# Try to find value from INTO variable in the record
|
||||
if val is None:
|
||||
for iv, scola in into_to_col.items():
|
||||
if scola == col_name and iv in rec:
|
||||
val = str(rec[iv])
|
||||
break
|
||||
|
||||
# Try COBOL field name mapping
|
||||
if val is None:
|
||||
cobol_field = guess_cobol_field(col_name, table, declared_columns)
|
||||
if cobol_field in rec:
|
||||
val = str(rec[cobol_field])
|
||||
|
||||
if val is not None:
|
||||
row[col_name] = _format_db_value(col_info, val)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user