2023-04-19 21:22:53 +02:00
#coding:utf-8
"""
ID : issue - 7548
ISSUE : https : / / github . com / FirebirdSQL / firebird / issues / 7548
TITLE : SET BIND OF TIMESTAMP WITH TIME ZONE TO CHAR is not working with UTF8 connection charset
DESCRIPTION :
Test checks all character sets defined in CHARSET_MAP dictionary ( see firebird / driver / core . py ) .
No errors must occur for all of them .
NOTES :
[ 19.04 .2023 ] pzotov
2023-08-31 19:50:21 +02:00
Confirmed bug on 4.0 .3 .2929 , 5.0 .0 .1014
2023-04-19 21:22:53 +02:00
Checked on 4.0 .3 .2931 , 5.0 .0 .1021 - all OK .
2023-08-31 19:50:21 +02:00
[ 31.08 .2023 ] pzotov
Refactored :
* output of checked timestamp can be suppressed , see redirection : ' out {os.devnull} ' ;
* there is no need to display the same error messages for many charsets ; rather , we can use dictionary
with key = error message and val = list of character sets which did not pass check ( i . e . for which
we get " SQLSTATE = 22001 / ... / -string right truncation / -expected length N, actual M " ;
* removed unneeded substitutions , use ' init ' arg for db_factory in order to make test run faster ;
2023-04-19 21:22:53 +02:00
"""
2023-08-31 19:50:21 +02:00
import os
2023-04-19 21:22:53 +02:00
import pytest
from firebird . qa import *
from firebird . driver import CHARSET_MAP
2023-08-31 19:50:21 +02:00
from collections import defaultdict
2023-04-19 21:22:53 +02:00
2023-08-31 19:50:21 +02:00
db = db_factory ( init = ' recreate table test(f01 timestamp with time zone); ' )
2023-04-19 21:22:53 +02:00
ts = ' 19-APR-2023 21:15:19.0110 '
test_sql = f """
set list on ;
2023-08-31 19:50:21 +02:00
delete from test ;
2023-04-19 21:22:53 +02:00
insert into test values ( timestamp ' {ts} ' ) ;
set term ^ ;
execute block as
begin
set bind of timestamp with time zone to char ;
end
^
set term ; ^
2023-08-31 19:50:21 +02:00
out { os . devnull } ;
2023-04-19 21:22:53 +02:00
select * from test ;
2023-08-31 19:50:21 +02:00
out ;
rollback ;
2023-04-19 21:22:53 +02:00
"""
2023-08-31 19:50:21 +02:00
act = python_act ( ' db ' )
2023-04-19 21:22:53 +02:00
2023-05-19 15:02:44 +02:00
@pytest.mark.version ( ' >=4.0.3 ' )
2023-04-19 21:22:53 +02:00
def test_1 ( act : Action , capsys ) :
cset_list = [ ]
with act . db . connect ( ) as con :
with con . cursor ( ) as cur :
cur . execute ( " select trim(c.rdb$character_set_name) from rdb$character_sets c where coalesce(c.rdb$system_flag,0)<>0 and c.rdb$character_set_name not in ( ' NONE ' , ' OCTETS ' ) " )
cset_list = [ x [ 0 ] for x in cur . fetchall ( ) if x [ 0 ] in CHARSET_MAP ]
2023-08-31 19:50:21 +02:00
# Result: cset_list = ['ASCII', 'UNICODE_FSS', 'UTF8', 'SJIS_0208', ..., 'KOI8U', 'WIN1258', 'GBK', 'GB18030']
2023-04-19 21:22:53 +02:00
2023-08-31 19:50:21 +02:00
cset_fails = defaultdict ( list )
for cset_i in cset_list :
2023-04-19 21:22:53 +02:00
act . reset ( )
2023-08-31 19:50:21 +02:00
act . expected_stdout = ' '
act . isql ( switches = [ ' -q ' ] , charset = cset_i , input = test_sql , combine_output = True )
2023-04-19 21:22:53 +02:00
if act . clean_stdout == act . clean_expected_stdout :
pass
else :
2023-08-31 19:50:21 +02:00
cset_fails [ act . clean_stdout ] + = cset_i ,
2023-04-19 21:22:53 +02:00
if cset_fails :
2023-08-31 19:50:21 +02:00
print ( ' Detected fails: ' )
2023-04-19 21:22:53 +02:00
for k , v in sorted ( cset_fails . items ( ) ) :
2023-08-31 19:50:21 +02:00
print ( ' Character sets: ' , ' , ' . join ( v ) )
2023-04-19 21:22:53 +02:00
print ( ' Result: ' )
2023-08-31 19:50:21 +02:00
print ( k )
2023-04-19 21:22:53 +02:00
print ( ' ' )
2023-08-31 19:50:21 +02:00
2023-04-19 21:22:53 +02:00
assert ' ' == capsys . readouterr ( ) . out