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:
@@ -154,6 +154,7 @@ class _BrParser:
|
||||
self.assignments = assignments if assignments is not None else {}
|
||||
self.fields = fields
|
||||
self._goto_depth = goto_depth
|
||||
self._cursors = {}
|
||||
|
||||
def peek(self):
|
||||
if self.pos < len(self.lines):
|
||||
@@ -1311,6 +1312,64 @@ class _BrParser:
|
||||
self.assignments.setdefault(synthetic, []).append(info)
|
||||
return Assign(synthetic, info)
|
||||
|
||||
# 4a) DECLARE CURSOR ... FOR SELECT ... FROM ...
|
||||
m = re.search(
|
||||
r'DECLARE\s+(\w[\w-]*)\s+CURSOR\s+FOR\s+SELECT\s+(.*?)\s+FROM\s+(\w[\w-]*)\s*(.*)',
|
||||
sql_text, re.IGNORECASE
|
||||
)
|
||||
if m:
|
||||
cursor_name = m.group(1).upper()
|
||||
select_list = m.group(2).strip()
|
||||
from_table = m.group(3).strip().upper()
|
||||
remaining = m.group(4).strip()
|
||||
|
||||
where_clause = ''
|
||||
wm = self._RE_WHERE.search(remaining)
|
||||
if wm:
|
||||
where_clause = wm.group(1).strip()
|
||||
|
||||
info = {
|
||||
'type': 'exec_sql_select',
|
||||
'cursor_name': cursor_name,
|
||||
'table': from_table,
|
||||
'select_list': select_list,
|
||||
'into_vars': [],
|
||||
'where': where_clause,
|
||||
'sql_text': sql_text,
|
||||
}
|
||||
synthetic = f'__SQL_CURSOR_{from_table}'
|
||||
self.assignments.setdefault(synthetic, []).append(info)
|
||||
self._cursors[cursor_name] = synthetic
|
||||
return Assign(synthetic, info)
|
||||
|
||||
# 4b) FETCH ... INTO ...
|
||||
m = re.search(r'FETCH\s+(\w[\w-]*)\s+INTO\s+(.+)', sql_text, re.IGNORECASE)
|
||||
if m:
|
||||
cursor_name = m.group(1).upper()
|
||||
into_raw = m.group(2).strip()
|
||||
into_vars = []
|
||||
for v in re.split(r'\s*,\s*', into_raw):
|
||||
v = v.strip().lstrip(':')
|
||||
parts = v.split(':')
|
||||
into_vars.append(parts[0].upper())
|
||||
|
||||
# Merge INTO vars into the corresponding DECLARE CURSOR entry
|
||||
syn_key = self._cursors.get(cursor_name)
|
||||
if syn_key:
|
||||
for existing in self.assignments.get(syn_key, []):
|
||||
if existing.get('cursor_name') == cursor_name:
|
||||
existing['into_vars'] = into_vars
|
||||
|
||||
info = {
|
||||
'type': 'exec_sql_fetch',
|
||||
'cursor_name': cursor_name,
|
||||
'into_vars': into_vars,
|
||||
'sql_text': sql_text,
|
||||
}
|
||||
for var in into_vars:
|
||||
self.assignments.setdefault(var, []).append(info)
|
||||
return Assign(into_vars[0], info)
|
||||
|
||||
# 4) UPDATE table SET ... WHERE ...
|
||||
m = self._RE_SQL_UPDATE.search(sql_text)
|
||||
if m:
|
||||
|
||||
Reference in New Issue
Block a user