87 lines
3.5 KiB
Python
87 lines
3.5 KiB
Python
"""BETWEEN WHERE 子句解析测试。
|
||
|
||
根因:KYU05DED 的 `WHERE :WRK-TAXABLE-INCOME BETWEEN TAX-FROM AND TAX-TO`:
|
||
1. `_split_on_AND` 把 BETWEEN 内部的 AND 当成分隔符切断,导致约束解析为空;
|
||
2. `_RE_BETWEEN` 要求首操作数为列名,不支持 `:主机变量 BETWEEN ...`。
|
||
修复后应能解析出 subject / lo / hi 三端(每端可为列名 / 主机变量 / 字面量)。
|
||
"""
|
||
|
||
import sys, os
|
||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..")))
|
||
from cobol_testgen.to_sql import _split_on_AND, sql_extract_constraints
|
||
|
||
|
||
def test_split_on_and_preserves_between():
|
||
"""BETWEEN 内部的 AND 不应被当作条件分隔符切断。"""
|
||
parts = _split_on_AND(':WRK-TAXABLE-INCOME BETWEEN TAX-FROM AND TAX-TO')
|
||
assert parts == [':WRK-TAXABLE-INCOME BETWEEN TAX-FROM AND TAX-TO']
|
||
|
||
|
||
def test_split_on_and_between_with_following_and():
|
||
"""BETWEEN 后的其他 AND 条件仍应正确切分。"""
|
||
parts = _split_on_AND(
|
||
'EMP-ID = :DBV-EMP-ID AND :WRK-TAXABLE-INCOME BETWEEN TAX-FROM AND TAX-TO AND STATUS = :S'
|
||
)
|
||
assert parts == [
|
||
'EMP-ID = :DBV-EMP-ID',
|
||
':WRK-TAXABLE-INCOME BETWEEN TAX-FROM AND TAX-TO',
|
||
'STATUS = :S',
|
||
]
|
||
|
||
|
||
def test_sql_extract_constraints_between_hostvar_subject():
|
||
"""`:主机变量 BETWEEN 列1 AND 列2`:subject 为主机变量,lo/hi 为列名。"""
|
||
cons = sql_extract_constraints(
|
||
':WRK-TAXABLE-INCOME BETWEEN TAX-FROM AND TAX-TO', 'TAX_TABLE', {}, {}, {})
|
||
assert len(cons) == 1
|
||
c = cons[0]
|
||
assert c['type'] == 'between'
|
||
assert c['neg'] is False
|
||
assert c['subject'] == {'kind': 'host_var', 'name': 'WRK-TAXABLE-INCOME'}
|
||
assert c['lo'] == {'kind': 'column', 'name': 'TAX-FROM'}
|
||
assert c['hi'] == {'kind': 'column', 'name': 'TAX-TO'}
|
||
|
||
|
||
def test_sql_extract_constraints_between_column_subject():
|
||
"""`列 BETWEEN :低 AND :高`:subject 为列名,lo/hi 为主机变量。"""
|
||
cons = sql_extract_constraints(
|
||
'SALARY BETWEEN :LO AND :HI', 'EMP', {}, {}, {})
|
||
assert len(cons) == 1
|
||
c = cons[0]
|
||
assert c['type'] == 'between'
|
||
assert c['subject'] == {'kind': 'column', 'name': 'SALARY'}
|
||
assert c['lo'] == {'kind': 'host_var', 'name': 'LO'}
|
||
assert c['hi'] == {'kind': 'host_var', 'name': 'HI'}
|
||
|
||
|
||
def test_sql_extract_constraints_between_compound():
|
||
"""BETWEEN 与其他条件组合时,全部解析且顺序保持。"""
|
||
cons = sql_extract_constraints(
|
||
'EMP-ID = :DBV-EMP-ID AND :WRK-TAXABLE-INCOME BETWEEN TAX-FROM AND TAX-TO',
|
||
'TAX_TABLE', {}, {}, {})
|
||
assert len(cons) == 2
|
||
assert cons[0]['type'] == 'host_var'
|
||
assert cons[0]['host_var'] == 'DBV-EMP-ID'
|
||
assert cons[1]['type'] == 'between'
|
||
|
||
|
||
def test_sql_extract_constraints_not_between():
|
||
"""NOT BETWEEN 正确解析 neg 标志。"""
|
||
cons = sql_extract_constraints(':X NOT BETWEEN A AND B', 'T', {}, {}, {})
|
||
assert len(cons) == 1
|
||
assert cons[0]['type'] == 'between'
|
||
assert cons[0]['neg'] is True
|
||
assert cons[0]['subject'] == {'kind': 'host_var', 'name': 'X'}
|
||
|
||
|
||
def test_sql_extract_constraints_between_three_part():
|
||
"""三段式:BETWEEN 之后跟后续 AND 条件。"""
|
||
cons = sql_extract_constraints(
|
||
':X BETWEEN A AND B AND :Y > 5', 'T', {}, {}, {})
|
||
assert len(cons) == 2
|
||
assert cons[0]['type'] == 'between'
|
||
assert cons[0]['lo'] == {'kind': 'column', 'name': 'A'}
|
||
assert cons[0]['hi'] == {'kind': 'column', 'name': 'B'}
|
||
assert cons[1]['type'] == 'literal'
|
||
assert cons[1]['op'] == '>'
|