Skip to content

Commit 73e8348

Browse files
committed
Added/Updated tests\functional\intfunc\unlist\unlist_output_value_has_separator_test.py: Checked on 6.0.0.744 (19-apr-2025) - all fine.
1 parent 7c8447b commit 73e8348

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#coding:utf-8
2+
3+
"""
4+
ID: issue-8418
5+
ISSUE: https://github.com/FirebirdSQL/firebird/issues/8418
6+
TITLE: Character <S> must NOT occur in any value generated by UNLIST which gets this <S> as separator.
7+
DESCRIPTION:
8+
Test restores two databases (clones of employee) that contain blob field that must be passed as argument to UNLIST().
9+
In both DB blobs were generated as random sequences of unicode characters from any avaliable ranges.
10+
None of values generated by UNLIST() must contain separator.
11+
But under some circumstatences this rule could be violated, see:
12+
https://github.com/FirebirdSQL/firebird/pull/8418#issuecomment-2781057324
13+
https://github.com/FirebirdSQL/firebird/pull/8418#issuecomment-2789227832
14+
NOTES:
15+
Confirmed bug on 6.0.0.742 (17-apr-2025): separator presented in some of generated values.
16+
Checked on 6.0.0.744 (19-apr-2025) - all fine.
17+
"""
18+
19+
from pathlib import Path
20+
import zipfile
21+
import locale
22+
import pytest
23+
from firebird.qa import *
24+
from firebird.driver import connect
25+
26+
db = db_factory(charset = 'utf8')
27+
act = python_act('db', substitutions=[('[ \t]+', ' ')])
28+
29+
tmp_fbk = temp_file('unlist_unexpected.tmp.fbk')
30+
tmp_fdb = temp_file('unlist_unexpected.tmp.fdb')
31+
32+
@pytest.mark.version('>=6.0.0')
33+
def test_1(act: Action, tmp_fbk: Path, tmp_fdb: Path, capsys):
34+
35+
test_map = {'unlist-unexpected-6_0_0_716-a5b25c1.fbk' : '0x227b', 'unlist-unexpected-6_0_0_717-fbb6b0c.fbk' : '0x2114'}
36+
expected_out = []
37+
for i_fbk, i_chr in test_map.items():
38+
39+
# 716: select u.* from unlist((select blob_fld from t_longblob), unicode_char(0x227b) returning blob character set utf8) as u(x) where x containing unicode_char(0x227b)
40+
# 717: select u.x, octet_length(u.x), position(unicode_char(0x2114) in u.x), unicode_char(0x2114) from unlist((select blob_fld from t_longblob), unicode_char(0x2114) returning blob character set utf8) as u(x) where x containing unicode_char(0x2114)
41+
42+
zipped_fbk_file = zipfile.Path(act.files_dir / 'unlist-unexpected.zip', at = i_fbk)
43+
tmp_fbk.write_bytes(zipped_fbk_file.read_bytes())
44+
45+
act.gbak(switches = ['-rep', str(tmp_fbk), str(tmp_fdb)], combine_output = True, io_enc = locale.getpreferredencoding())
46+
assert '' == act.stdout
47+
act.reset()
48+
49+
test_sql = f"""
50+
with
51+
d as (
52+
select
53+
blob_fld
54+
,unicode_char({i_chr}) as separator
55+
from t_longblob
56+
)
57+
, e as (
58+
select * from d, unlist(d.blob_fld, d.separator returning blob character set utf8) as u (unlist_token)
59+
)
60+
select e.unlist_token, position(e.separator in e.unlist_token) as separator_pos
61+
from e
62+
where e.unlist_token containing e.separator
63+
;
64+
"""
65+
66+
with connect(str(tmp_fdb), user = act.db.user, password = act.db.password, charset = 'utf8') as con:
67+
print(i_fbk)
68+
expected_out.append(i_fbk)
69+
cur = con.cursor()
70+
cur.execute(test_sql)
71+
data = cur.fetchall()
72+
if data:
73+
print(f'### ERROR ### separator {i_chr} occurs at least in one record issued by UNLIST():')
74+
75+
col = cur.description
76+
for r in data:
77+
for i in range(len(col)):
78+
print(' '.join((col[i][0], ':', str(r[i]))))
79+
80+
81+
act.expected_stdout = '\n'.join(expected_out)
82+
83+
act.stdout = capsys.readouterr().out
84+
assert act.clean_stdout == act.clean_expected_stdout

0 commit comments

Comments
 (0)