6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 21:43:06 +01:00
firebird-qa/tests/bugs/gh_7846_test.py

191 lines
8.1 KiB
Python

#coding:utf-8
"""
ID: issue-7846
ISSUE: https://github.com/FirebirdSQL/firebird/issues/7846
TITLE: FB4 can't backup/restore int128-array
DESCRIPTION:
Test checks ability to make b/r of DB with table that has array-based columns of following types:
smallint; integer; bigint; int128; double.
NOTES:
[16.09.2024] pzotov
1. Confirmed problem with b/r for INT128 on 4.0.4.3021 (dob: 17-nov-2023).
Got after restore: [Decimal('0'), Decimal('0')] (although no errors were during insert origin data).
Expected values: [Decimal('170141183460469231731687303715884105727'), Decimal('-170141183460469231731687303715884105728')].
Confirmed fix on 4.0.4.3022 (dob: 19-nov-2023).
2. Fix for #8100 ("The isc_array_lookup_bounds function returns invalid values...") required in order
this test can pass on FB 5.x and 6.x.
See commits (07-may-2024):
* 5.x: https://github.com/FirebirdSQL/firebird/commit/26ca064202169c0558359fc9ab06b70e827466f0
* 6.x: https://github.com/FirebirdSQL/firebird/commit/17b007d14f8ccc6cfba0d63a3b2f21622ced20d0
FB 4.x was not affected by that bug.
3. INT128 type requires as argument only INTEGER values (from scope -2**127 ... +2**127-1) but NOT decimals.
Rather, NUMERIC / DECIMAL columns allows only Decimal instances.
(letter from Alex, 20.08.2024 16:11, subj: "gh-6544 ("Error writing an array of NUMERIC(24,6)" ) <...>"
4. DECFLOAT type had a problem in firebird-driver, fixed in v 1.10.5 (26-JUL-2024)
5. Some features must be implemented in engine and/or in firebird-driver for proper support of NUMERIC datatype
which have big values and use int128 as underlying storage.
Discussed with pcisar, see subj "firebird-driver and its support for FB datatypes", letters since 21-jul-2024.
See also: https://github.com/FirebirdSQL/firebird/issues/6544#issuecomment-2294778138
Checked on 6.0.0.457; 5.0.2.1499; 4.0.5.3136.
"""
import pytest
from firebird.qa import *
from io import BytesIO
from firebird.driver import SrvRestoreFlag, DatabaseError, InterfaceError
from decimal import Decimal
import traceback
import time
init_script = """
recreate table test_arr(
id int generated by default as identity constraint test_pk primary key
,v_smallint smallint[2]
,v_integer int[2]
,v_bigint bigint[2]
,v_int128 int128[2]
,v_double double precision[2]
,v_decfloat decfloat[2]
);
"""
db = db_factory(init = init_script)
act = python_act('db')
#--------------------------------------
def try_insert(con, cur, fld, data):
print(f'\nTrying to add array in {fld}')
try:
print(f'Data: {data}')
with cur.prepare(f"insert into test_arr({fld}) values (?)") as ps:
for x in data:
cur.execute(ps, (x,))
cur.execute(f'select {fld} from test_arr order by id desc rows 1')
for r in cur:
for x in r[0]:
print(x, type(x))
con.commit()
print('Success.')
#except (ValueError, InterfaceError, DatabaseError) as e:
except Exception as e:
for x in traceback.format_exc().split('\n'):
print(' ',x)
#--------------------------------------
@pytest.mark.version('>=4.0.5')
def test_1(act: Action, capsys):
with act.db.connect() as con:
cur = con.cursor()
# ------------ smallint -------------
data = [ [32767, -32768] ]
try_insert(con, cur, 'v_smallint', data)
# ------------ int -------------
data = [ [2147483647, -2147483648] ]
try_insert(con, cur, 'v_integer', data)
# ------------ bigint -------------
data = [ [9223372036854775807, -9223372036854775808] ]
try_insert(con, cur, 'v_bigint', data)
# ------------ int128 -------------
# sqltype: 32752 INT128 Nullable scale: 0 subtype: 0 len: 16
# ValueError: Incorrect ARRAY field value.
# !! WRONG!! >>> data = [ [Decimal('170141183460469231731687303715884105727'), Decimal('-170141183460469231731687303715884105728')] ]
# Only INTEGERS must be specified as arguments:
data = [ [170141183460469231731687303715884105727, -170141183460469231731687303715884105728] ]
try_insert(con, cur, 'v_int128', data)
# ------------ double -------------
data = [ [-2.2250738585072014e-308, 1.7976931348623158e+308] ]
try_insert(con, cur, 'v_double', data)
# ------------ decfloat -------------
# ValueError: Incorrect ARRAY field value.
# data = [ [Decimal('-1.0E-6143'), Decimal('9.999999999999999999999999999999999E6144')] ]
# data = [ [-1.0E-6143, 9.999999999999999999999999999999999E6144] ]
data = [ [Decimal('-9.999999999999999999999999999999999E+6144'), Decimal('9.999999999999999999999999999999999E+6144')] ]
try_insert(con, cur, 'v_decfloat', data)
backup = BytesIO()
with act.connect_server() as srv:
srv.database.local_backup(database=act.db.db_path, backup_stream=backup)
backup.seek(0)
srv.database.local_restore(backup_stream=backup, database=act.db.db_path, flags = SrvRestoreFlag.REPLACE)
with act.db.connect() as con:
cur = con.cursor()
for fld_name in ('v_smallint','v_integer','v_bigint','v_int128','v_double', 'v_decfloat'):
cur.execute(f'select {fld_name} from test_arr')
for r in cur:
# type(r): <class 'tuple'>
if any(r):
print(f'Result after restore for column {fld_name}:')
for p in r:
print(p)
act.expected_stdout = """
Trying to add array in v_smallint
Data: [[32767, -32768]]
32767 <class 'int'>
-32768 <class 'int'>
Success.
Trying to add array in v_integer
Data: [[2147483647, -2147483648]]
2147483647 <class 'int'>
-2147483648 <class 'int'>
Success.
Trying to add array in v_bigint
Data: [[9223372036854775807, -9223372036854775808]]
9223372036854775807 <class 'int'>
-9223372036854775808 <class 'int'>
Success.
Trying to add array in v_int128
Data: [[170141183460469231731687303715884105727, -170141183460469231731687303715884105728]]
170141183460469231731687303715884105727 <class 'decimal.Decimal'>
-170141183460469231731687303715884105728 <class 'decimal.Decimal'>
Success.
Trying to add array in v_double
Data: [[-2.2250738585072014e-308, 1.7976931348623157e+308]]
-2.2250738585072014e-308 <class 'float'>
1.7976931348623157e+308 <class 'float'>
Success.
Trying to add array in v_decfloat
Data: [[Decimal('-9.999999999999999999999999999999999E+6144'), Decimal('9.999999999999999999999999999999999E+6144')]]
-9.999999999999999999999999999999999E+6144 <class 'decimal.Decimal'>
9.999999999999999999999999999999999E+6144 <class 'decimal.Decimal'>
Success.
Result after restore for column v_smallint:
[32767, -32768]
Result after restore for column v_integer:
[2147483647, -2147483648]
Result after restore for column v_bigint:
[9223372036854775807, -9223372036854775808]
Result after restore for column v_int128:
[Decimal('170141183460469231731687303715884105727'), Decimal('-170141183460469231731687303715884105728')]
Result after restore for column v_double:
[-2.2250738585072014e-308, 1.7976931348623157e+308]
Result after restore for column v_decfloat:
[Decimal('-9.999999999999999999999999999999999E+6144'), Decimal('9.999999999999999999999999999999999E+6144')]
"""
act.stdout = capsys.readouterr().out
assert act.clean_stdout == act.clean_expected_stdout