2021-04-26 20:07:00 +02:00
#coding:utf-8
2022-01-18 20:45:21 +01:00
"""
ID : issue - 1393
2024-09-04 15:45:16 +02:00
ISSUE : https : / / github . com / FirebirdSQL / firebird / issues / 1393
2022-01-18 20:45:21 +01:00
TITLE : Non - ASCII quoted identifiers are not converted to metadata ( UNICODE_FSS ) charset
DESCRIPTION :
JIRA : CORE - 986
2022-02-02 15:46:19 +01:00
FBTEST : bugs . core_0986
2023-11-25 16:41:21 +01:00
NOTES :
[ 25.11 .2023 ] pzotov
2024-09-22 23:08:10 +02:00
Writing code requires more care since 6.0 .0 .150 : ISQL does not allow specifying duplicate delimiters without any statements between them ( two semicolon , two carets etc )
2022-01-18 20:45:21 +01:00
"""
2021-04-26 20:07:00 +02:00
import pytest
2022-01-18 20:45:21 +01:00
from firebird . qa import *
2021-11-10 19:02:05 +01:00
from pathlib import Path
2021-04-26 20:07:00 +02:00
2022-01-18 20:45:21 +01:00
db = db_factory ( )
act = python_act ( ' db ' , substitutions = [ ( ' in file .* ' , ' in file XXX ' ) ] )
expected_stdout_a = """ create collation " Циферки " for utf8 from unicode case insensitive ' NUMERIC-SORT=1 ' ; """
expected_stderr_a_40 = """
2024-09-04 11:43:07 +02:00
Statement failed , SQLSTATE = 22018
arithmetic exception , numeric overflow , or string truncation
- Cannot transliterate character between character sets
After line 4 in file non_ascii_ddl . sql
2021-11-10 19:02:05 +01:00
"""
2022-01-18 20:45:21 +01:00
expected_stderr_a_30 = """
2024-09-04 11:43:07 +02:00
Statement failed , SQLSTATE = 22000
unsuccessful metadata update
- CREATE COLLATION Циферки failed
- Malformed string
After line 4 in file non_ascii_ddl . sql
2021-11-10 19:02:05 +01:00
"""
non_ascii_ddl = '''
set bail on ;
set echo on ;
create collation " Циферки " for utf8 from unicode case insensitive ' NUMERIC-SORT=1 ' ;
2023-11-25 16:41:21 +01:00
create collation " Испания " for iso8859_1 from es_es_ci_ai ' SPECIALS-FIRST=1 ' ;
2021-11-10 19:02:05 +01:00
commit ;
create domain " ИД ' шники " int ;
create domain " Группы " varchar ( 30 ) check ( value in ( ' Электрика ' , ' Ходовая ' , ' Арматурка ' , ' Кузовщина ' ) ) ;
create domain " Артикулы " varchar ( 12 ) character set utf8 check ( value = upper ( value ) )
collate " Циферки " - - enabled since core - 5220 was fixed ( 30.04 .2016 )
;
create domain " Комрады " varchar ( 40 ) character set iso8859_1
collate " Испания " - - enabled since core - 5220 was fixed ( 30.04 .2016 )
;
create domain " Кол-во " numeric ( 12 , 3 ) not null ;
create sequence generilka ;
create sequence " Генерилка " ;
create role " манагер " ;
create role " начсклд " ;
2024-09-04 15:45:16 +02:00
- - enabled since CORE - 5209 was fixed :
2021-11-10 19:02:05 +01:00
recreate exception " Невзлет " ' Запись обломалась, ваши не пляшут. Н о не стесняйтесь и обязательно заходите еще, мы всегда рады видеть вас. До скорой встречи, товарищ! ' ;
commit ;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
recreate table " склад " (
" ИД ' шник " " ИД ' шники "
, " Откудова " " Группы "
, " Номенклатура " " Артикулы "
, " ИД ' родителя " " ИД ' шники "
, " сколько там " " Кол-во "
, constraint " ПК-ИД ' шник " primary key ( " ИД ' шник " ) using index " с кла д_ПК "
, constraint " ФК-на-родока " foreign key ( " ИД ' родителя " ) references " склад " ( " ИД ' шник " ) using index " с кла д_ФК "
, constraint " остаток >=0 " check ( " сколько там " > = 0 )
) ;
recreate view " Электрика " ( " ид изделия " , " Название " , " Запас " ) as
select
" ИД ' шник "
, " Номенклатура "
, " сколько там "
from " склад "
where " Откудова " = ' Электрика '
;
set term ^ ;
create or alter trigger " склад би " for " склад " active before insert as
begin
- - new . " ИД ' шник " = coalesce ( new . " ИД ' шник " , gen_id ( generilka , 1 ) ) ;
- - not avail up to 2.5 .6 :
new . " ИД ' шник " = coalesce ( new . " ИД ' шник " , gen_id ( " Генерилка " , 1 ) ) ;
end
^
create or alter procedure " Доб на склад " (
" Откудова " varchar ( 30 )
, " Номенклатура " varchar ( 30 )
, " ИД ' родителя " int
, " сколько там " numeric ( 12 , 3 )
) returns (
" код возврата " int
) as
begin
insert into " склад " (
" Откудова "
, " Номенклатура "
, " ИД ' родителя "
, " сколько там "
) values (
: " Откудова "
, : " Номенклатура "
, : " ИД ' родителя "
, : " сколько там "
) ;
end
^
create or alter procedure " Удалить " as
begin
/ *
Антон Павлович Чехов . Каштанка
1. Дурное поведение
Молодая рыжая собака - помесь такса с дворняжкой - очень похожая мордой
на лисицу , бегала взад и вперед по тротуару и беспокойно оглядывалась по
сторонам . Изредка она останавливалась и , плача , приподнимая то одну озябшую
лапу , то другую , старалась дать с е б е отчет : как это могло случиться , что она
заблудилась ?
* /
end
^
set term ; ^
grant select on " склад " to " манагер " ;
grant select , insert , update , delete on " склад " to " начсклд " ;
- - no avail in 2.0 : grant execute procedure " Доб на склад " to " начсклд " ;
comment on sequence " Генерилка " is ' Генератор простых идей ' ;
comment on table " склад " is ' Это всё, что мы сейчас имеем в наличии ' ;
comment on view " Электрика " is ' Н е суй пальцы в розетку, будет б о -б о !' ;
comment on procedure " Доб на склад " is ' Процедурка добавления изделия на склад ' ;
comment on parameter " Доб на склад " . " Откудова " is ' Группа изделия, которое собираемся добавить ' ;
comment on parameter " Доб на склад " . " ИД ' родителя " is '
Федор Михайлович Достоевский
Преступление и наказание
Роман в шести частях с эпилогом
Часть первая
I
В начале июля , в чрезвычайно жаркое время , под вечер , один молодой человек вышел из своей каморки , которую нанимал от жильцов в С - - м переулке , на улицу и медленно , как бы в нерешимости , отправился к К - - ну мосту .
Он благополучно избегнул встречи с своею хозяйкой на лестнице . Каморка е г о приходилась под самою кровлей высокого пятиэтажного дома и походила более на шкаф , чем на квартиру . Квартирная же хозяйка е г о , у которой он нанимал эту каморку с обедом и прислугой , помещалась одною лестницей ниже , в отдельной квартире , и каждый раз , при выходе на улицу , ему непременно надо было проходить мимо хозяйкиной кухни , почти всегда настежь отворенной на лестницу . И каждый раз молодой человек , проходя мимо , чувствовал какое - то болезненное и трусливое ощущение , которого стыдился и от которого морщился . Он был должен кругом хозяйке и боялся с нею встретиться .
Н е то чтоб он был так труслив и забит , совсем даже напротив ; но с некоторого времени он был в раздражительном и напряженном состоянии , похожем на ипохондрию . Он до того углубился в себя и уединился от всех , что боялся даже всякой встречи , не только встречи с хозяйкой . Он был задавлен бедностью ; но даже стесненное положение перестало в последнее время тяготить е г о . Насущными делами своими он совсем перестал и не хотел заниматься . Никакой хозяйки , в сущности , он не боялся , что бы та ни замышляла против него . Н о останавливаться на лестнице , слушать всякий вздор про всю эту обыденную дребедень , до которой ему нет никакого дела , все эти приставания о платеже , угрозы , жалобы , и при этом самому изворачиваться , извиняться , лгать , - - нет уж , лучше проскользнуть как - нибудь кошкой по лестнице и улизнуть , чтобы никто не видал .
Впрочем , на этот раз страх встречи с своею кредиторшей даже е г о самого поразил по выходе на улицу .
" Н а какое дело хочу покуситься и в то же время каких пустяков боюсь! -- подумал он с странною улыбкой. -- Гм... да... всё в руках человека, и всё-то он мимо носу проносит, единственно от одной трусости... это уж аксиома... Любопытно, чего люди больше всего боятся? Нового шага, нового собственного слова они всего больше боятся... А впрочем, я слишком много болтаю. Оттого и ничего не делаю, что болтаю. Пожалуй, впрочем, и так: оттого болтаю, что ничего не делаю. Это я в этот последний месяц выучился болтать, лежа по целым суткам в углу и думая... о царе Горохе. Н у зачем я теперь иду? Разве я способен на это? Разве это серьезно? Совсем не серьезно. Так, ради фантазии сам себя тешу; игрушки! Да, пожалуй что и игрушки!"
Н а улице жара стояла страшная , к тому же духота , толкотня , всюду известка , леса , кирпич , пыль и та особенная летняя вонь , столь известная каждому петербуржцу , не имеющему возможности нанять дачу , - - всё это разом неприятно потрясло и без того уже расстроенные нервы юноши . Нестерпимая же вонь из распивочных , которых в этой части города особенное множество , и пьяные , поминутно попадавшиеся , несмотря на буднее время , довершили отвратительный и грустный колорит картины . Чувство глубочайшего омерзения мелькнуло на миг в тонких чертах молодого человека . Кстати , он был замечательно хорош собою , с прекрасными темными глазами , темно - р у с , ростом выше среднего , тонок и строен . Н о скоро он впал как бы в глубокую задумчивость , даже , вернее сказать , как бы в какое - то забытье , и пошел , уже не замечая окружающего , да и не желая е г о замечать . Изредка только бормотал он что - то про себя , от своей привычки к монологам , в которой он сейчас сам с е б е признался . В эту же минуту он и сам сознавал , что мысли е г о порою мешаются и что он очень слаб : второй день как уж он почти совсем ничего не ел .
Он был до того худо одет , что иной , даже и привычный человек , посовестился бы днем выходить в таких лохмотьях на улицу . Впрочем , квартал был таков , что костюмом здесь было трудно кого - нибудь удивить . Близость Сенной , обилие известных заведений и , по преимуществу , цеховое и ремесленное население , скученное в этих серединных петербургских улицах и переулках , пестрили иногда общую панораму такими субъектами , что странно было бы и удивляться при встрече с иною фигурой . Н о столько злобного презрения уже накопилось в душе молодого человека , что , несмотря на всю свою , иногда очень молодую , щекотливость , он менее всего совестился своих лохмотьев на улице . Другое дело при встрече с иными знакомыми или с прежними товарищами , с которыми вообще он не любил встречаться . . . А между тем , когда один пьяный , которого неизвестно почему и куда провозили в это время по улице в огромной телеге , запряженной огромною ломовою лошадью , крикнул ему вдруг , проезжая : " Эй ты, немецкий шляпник! " - - и заорал во всё горло , указывая на него рукой , - - молодой человек вдруг остановился и судорожно схватился за свою шляпу . Шляпа эта была высокая , круглая , циммермановская , но вся уже изношенная , совсем рыжая , вся в дырах и пятнах , без полей и самым безобразнейшим углом заломившаяся на сторону . Н о не стыд , а совсем другое чувство , похожее даже на испуг , охватило е г о .
" Я так и знал! -- бормотал он в смущении, -- я так и думал! Это уж всего сквернее! Вот эдакая какая-нибудь глупость, какая-нибудь пошлейшая мелочь, весь замысел может испортить! Да, слишком приметная шляпа... Смешная, потому и приметная... К моим лохмотьям непременно нужна фуражка, хотя бы старый блин какой-нибудь, а не этот урод. Никто таких не носит, за версту заметят, запомнят... главное, потом запомнят, ан и улика. Тут нужно быть как можно неприметнее... Мелочи, мелочи главное!.. Вот эти-то мелочи и губят всегда и всё... "
' ;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
commit ;
set echo on ;
show collation ;
show domain ;
show exception ; - - << << << << << << <
show sequence ;
show table ;
show trigger ;
show view ;
show procedure ;
show role ;
set list on ;
set echo off ;
select ' Metadata created OK. ' as msg from rdb $ database ;
'''
2024-09-04 11:43:07 +02:00
tmp_file = temp_file ( ' tmp_0986_non_ascii_ddl.sql ' )
2021-04-26 20:07:00 +02:00
2024-10-31 11:17:14 +01:00
@pytest.mark.intl
2021-04-26 20:07:00 +02:00
@pytest.mark.version ( ' >=3.0 ' )
2022-01-18 20:45:21 +01:00
def test_1 ( act : Action , tmp_file : Path ) :
tmp_file . write_bytes ( non_ascii_ddl . encode ( ' cp1251 ' ) )
2024-09-04 11:43:07 +02:00
2021-11-10 19:02:05 +01:00
# run without specifying charset
2024-09-04 11:43:07 +02:00
################################
2022-01-18 20:45:21 +01:00
act . expected_stdout = expected_stdout_a
act . expected_stderr = expected_stderr_a_40 if act . is_version ( ' >=4.0 ' ) else expected_stderr_a_30
act . isql ( switches = [ ' -q ' ] , input_file = tmp_file , charset = None , io_enc = ' cp1251 ' )
assert ( act . clean_stdout == act . clean_expected_stdout and
act . clean_stderr == act . clean_expected_stderr )
2024-09-04 11:43:07 +02:00
# run _with_ charset
####################
2022-01-18 20:45:21 +01:00
act . reset ( )
act . isql ( switches = [ ' -q ' ] , input_file = tmp_file , charset = ' win1251 ' , io_enc = ' cp1251 ' )
assert act . clean_stdout . endswith ( ' Metadata created OK. ' )