mirror of
https://github.com/FirebirdSQL/firebird-qa.git
synced 2025-01-22 13:33:07 +01:00
Change name scheme for tests
This commit is contained in:
parent
3081aa0974
commit
a4111205c3
34
tests/bugs/core_0000_test.py
Normal file
34
tests/bugs/core_0000_test.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0000
|
||||||
|
# title: Dummy test
|
||||||
|
# decription:
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0000
|
||||||
|
# min_versions: ['4.0']
|
||||||
|
# versions: 4.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 4.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table t1(id int);
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.version('>=4.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.execute()
|
||||||
|
|
46
tests/bugs/core_0001_test.py
Normal file
46
tests/bugs/core_0001_test.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0001
|
||||||
|
# title: FBserver shutsdown when a user password is attempted to be modified to a empty string
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0001
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create or alter user tmp$c0001 password '123';
|
||||||
|
commit;
|
||||||
|
alter user tmp$c0001 password '';
|
||||||
|
commit;
|
||||||
|
drop user tmp$c0001;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 42000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER USER TMP$C0001 failed
|
||||||
|
-Password should not be empty string
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
60
tests/bugs/core_0002_test.py
Normal file
60
tests/bugs/core_0002_test.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0002
|
||||||
|
# title: Incorrect value returned with execute statement calculation
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0002
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
create table t1 (
|
||||||
|
campo1 numeric(15,2),
|
||||||
|
campo2 numeric(15,2)
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
set term ^;
|
||||||
|
create procedure teste
|
||||||
|
returns (
|
||||||
|
retorno numeric(15,2))
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
execute statement 'select first 1 (campo1*campo2) from t1' into :retorno;
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into t1 (campo1, campo2) values (10.5, 5.5);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
select * from teste;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
RETORNO 57.75
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
51
tests/bugs/core_0010_test.py
Normal file
51
tests/bugs/core_0010_test.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0010
|
||||||
|
# title: Navigation vs IS NULL vs compound index
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0010
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table t (f1 int, f2 int);
|
||||||
|
create index t_idx on t (f1, f2);
|
||||||
|
|
||||||
|
insert into t (f1, f2) values (1, 1);
|
||||||
|
insert into t (f1, f2) values (null, 2);
|
||||||
|
insert into t (f1, f2) values (3, 3);
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
select *
|
||||||
|
from t
|
||||||
|
where f1 is null
|
||||||
|
order by f1, f2;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
F1 <null>
|
||||||
|
F2 2
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
187
tests/bugs/core_0014_test.py
Normal file
187
tests/bugs/core_0014_test.py
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0014
|
||||||
|
# title: Trigger do it wrong
|
||||||
|
# decription: Computed by columns inside triggers always=NULL
|
||||||
|
# tracker_id: CORE-0014
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
-- Works OK on 1.5.6 and up to 4.0.0.
|
||||||
|
create domain dom_datum_vreme as timestamp not null;
|
||||||
|
create domain dom_dokid as varchar(20) not null;
|
||||||
|
create domain dom_jid as integer;
|
||||||
|
create domain dom_kolicina as integer default 0;
|
||||||
|
create domain dom_naziv as varchar(100) not null;
|
||||||
|
create domain dom_novac as double precision default 0;
|
||||||
|
create domain dom_rabat as float default 0;
|
||||||
|
create domain dom_status as integer default 0;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create table ulaz_master
|
||||||
|
(
|
||||||
|
ulzid dom_jid not null,
|
||||||
|
datum dom_datum_vreme not null,
|
||||||
|
broj_racuna dom_dokid not null,
|
||||||
|
dobid dom_jid not null,
|
||||||
|
dobavljac dom_naziv not null,
|
||||||
|
napid dom_jid not null,
|
||||||
|
nacin_placanja dom_naziv not null,
|
||||||
|
datumprispeca timestamp, -- dom_datum_vreme null ,
|
||||||
|
vrednost dom_novac default 0,
|
||||||
|
rvrednost dom_novac default 0,
|
||||||
|
status dom_status default 0,
|
||||||
|
constraint pk_ulaz_master primary key (ulzid)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table ulaz_detalji
|
||||||
|
(
|
||||||
|
ulzid dom_jid not null,
|
||||||
|
artid dom_jid not null,
|
||||||
|
artikal dom_naziv not null,
|
||||||
|
kolicina dom_kolicina default 0 not null,
|
||||||
|
cena dom_novac default 0 not null,
|
||||||
|
rabat dom_rabat default 0 not null,
|
||||||
|
ukupno computed by (kolicina * cena),
|
||||||
|
vratio dom_kolicina default 0,
|
||||||
|
constraint pk_ulaz_detalji primary key (ulzid, artid)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create trigger trig_ulaz_detalji_ai for ulaz_detalji
|
||||||
|
active after insert position 0
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
|
||||||
|
update ulaz_master u set u.vrednost = u.vrednost + new.ukupno
|
||||||
|
where u.ulzid = new.ulzid;
|
||||||
|
|
||||||
|
update ulaz_master u set u.rvrednost = u.rvrednost + (1 - new.rabat/100) * new.ukupno
|
||||||
|
where u.ulzid = new.ulzid;
|
||||||
|
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
-- this trigger sets fiedls to null on rc8.
|
||||||
|
-- on rc6 it works as it should.
|
||||||
|
|
||||||
|
insert into ulaz_master(ulzid, datum, broj_racuna, dobid, dobavljac, napid, nacin_placanja)
|
||||||
|
values(1000, '19.03.2016 12:01:03', 'qwerty123', 78966, 'foo-bar', 32101, 'asd-fgh-jkl' );
|
||||||
|
/*
|
||||||
|
create domain dom_datum_vreme as timestamp not null;
|
||||||
|
create domain dom_dokid as varchar(20) not null;
|
||||||
|
create domain dom_jid as integer;
|
||||||
|
create domain dom_kolicina as integer default 0;
|
||||||
|
create domain dom_naziv as varchar(100) not null;
|
||||||
|
create domain dom_novac as double precision default 0;
|
||||||
|
create domain dom_rabat as float default 0;
|
||||||
|
create domain dom_status as integer default 0;
|
||||||
|
|
||||||
|
datum dom_datum_vreme not null,
|
||||||
|
broj_racuna dom_dokid not null,
|
||||||
|
dobid dom_jid not null,
|
||||||
|
dobavljac dom_naziv not null,
|
||||||
|
napid dom_jid not null,
|
||||||
|
nacin_placanja dom_naziv not null,
|
||||||
|
*/
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
set count on;
|
||||||
|
|
||||||
|
select
|
||||||
|
ulzid, datum, broj_racuna, dobid, dobavljac, napid, nacin_placanja, datumprispeca
|
||||||
|
,cast(vrednost as numeric(10,2)) as vrednost
|
||||||
|
,cast(rvrednost as numeric(10,2)) as rvrednost
|
||||||
|
,status
|
||||||
|
from ulaz_master;
|
||||||
|
|
||||||
|
insert into
|
||||||
|
ulaz_detalji(ulzid, artid, artikal, kolicina, cena, rabat, vratio)
|
||||||
|
values(1000, 1000, 'liste', 19, 7, 30, 0);
|
||||||
|
|
||||||
|
select
|
||||||
|
ulzid, artid, artikal, kolicina,
|
||||||
|
cast(cena as numeric(12,2)) as cena,
|
||||||
|
rabat,
|
||||||
|
cast(ukupno as numeric(12,2)) as ukupno,
|
||||||
|
vratio
|
||||||
|
from ulaz_detalji;
|
||||||
|
|
||||||
|
select
|
||||||
|
ulzid, datum, broj_racuna, dobid, dobavljac, napid, nacin_placanja, datumprispeca
|
||||||
|
,cast(vrednost as numeric(10,2)) as vrednost
|
||||||
|
,cast(rvrednost as numeric(10,2)) as rvrednost
|
||||||
|
,status
|
||||||
|
from ulaz_master;
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
ULZID 1000
|
||||||
|
DATUM 2016-03-19 12:01:03.0000
|
||||||
|
BROJ_RACUNA qwerty123
|
||||||
|
DOBID 78966
|
||||||
|
DOBAVLJAC foo-bar
|
||||||
|
NAPID 32101
|
||||||
|
NACIN_PLACANJA asd-fgh-jkl
|
||||||
|
DATUMPRISPECA <null>
|
||||||
|
VREDNOST 0.00
|
||||||
|
RVREDNOST 0.00
|
||||||
|
STATUS 0
|
||||||
|
|
||||||
|
|
||||||
|
Records affected: 1
|
||||||
|
Records affected: 1
|
||||||
|
|
||||||
|
ULZID 1000
|
||||||
|
ARTID 1000
|
||||||
|
ARTIKAL liste
|
||||||
|
KOLICINA 19
|
||||||
|
CENA 7.00
|
||||||
|
RABAT 30
|
||||||
|
UKUPNO 133.00
|
||||||
|
VRATIO 0
|
||||||
|
|
||||||
|
|
||||||
|
Records affected: 1
|
||||||
|
|
||||||
|
ULZID 1000
|
||||||
|
DATUM 2016-03-19 12:01:03.0000
|
||||||
|
BROJ_RACUNA qwerty123
|
||||||
|
DOBID 78966
|
||||||
|
DOBAVLJAC foo-bar
|
||||||
|
NAPID 32101
|
||||||
|
NACIN_PLACANJA asd-fgh-jkl
|
||||||
|
DATUMPRISPECA <null>
|
||||||
|
VREDNOST 133.00
|
||||||
|
RVREDNOST 93.10
|
||||||
|
STATUS 0
|
||||||
|
|
||||||
|
Records affected: 1
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
101
tests/bugs/core_0037_test.py
Normal file
101
tests/bugs/core_0037_test.py
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0037
|
||||||
|
# title: Navigation vs IS NULL vs compound index
|
||||||
|
# decription:
|
||||||
|
# 24.01.2019. Added separate code for running on FB 4.0+.
|
||||||
|
# UDF usage is deprecated in FB 4+, see: ".../doc/README.incompatibilities.3to4.txt".
|
||||||
|
# Functions div, frac, dow, sdow, getExactTimestampUTC and isLeapYear got safe replacement
|
||||||
|
# in UDR library "udf_compat", see it in folder: ../plugins/udr/
|
||||||
|
# Checked on:
|
||||||
|
# 2.5.9.27126: OK, 0.656s.
|
||||||
|
# 3.0.5.33086: OK, 1.422s.
|
||||||
|
# 4.0.0.1172: OK, 4.109s.
|
||||||
|
# 4.0.0.1340: OK, 2.297s.
|
||||||
|
# 4.0.0.1378: OK, 2.204s.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0037
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 4.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 4.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set bail on;
|
||||||
|
|
||||||
|
-- See declaration sample in plugins\\udr\\UdfBackwardCompatibility.sql:
|
||||||
|
|
||||||
|
create function UDR40_frac (
|
||||||
|
val double precision
|
||||||
|
) returns double precision
|
||||||
|
external name 'udf_compat!UC_frac'
|
||||||
|
engine udr;
|
||||||
|
|
||||||
|
recreate view v1 as select 1 k from rdb$database;
|
||||||
|
recreate view v2 as select 1 k from rdb$database;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate table t1
|
||||||
|
(
|
||||||
|
t1f1 integer not null primary key,
|
||||||
|
t1f2 varchar(30)
|
||||||
|
);
|
||||||
|
|
||||||
|
recreate table t2
|
||||||
|
(
|
||||||
|
t2f1 integer not null primary key,
|
||||||
|
t2f2 integer not null,
|
||||||
|
t2f3 varchar(30)
|
||||||
|
);
|
||||||
|
|
||||||
|
create index t2f2_ndx on t2(t2f2);
|
||||||
|
|
||||||
|
recreate view v1 as select * from t1 where UDR40_frac( mod(t1f1,100) / 100.000) > 0.03;
|
||||||
|
recreate view v2 as select * from t2 where UDR40_frac( mod(t2f1,100) / 100.000) > 0.03;
|
||||||
|
|
||||||
|
insert into t1(t1f1, t1f2) values (1, '1');
|
||||||
|
insert into t1(t1f1, t1f2) values (2, '2');
|
||||||
|
insert into t1(t1f1, t1f2) values (3, '3');
|
||||||
|
insert into t1(t1f1, t1f2) values (104, '104');
|
||||||
|
insert into t1(t1f1, t1f2) values (105, '205');
|
||||||
|
insert into t1(t1f1, t1f2) values (106, '106');
|
||||||
|
|
||||||
|
insert into t2(t2f1, t2f2, t2f3) values (1, 1, '1');
|
||||||
|
insert into t2(t2f1, t2f2, t2f3) values (2, 2, '2');
|
||||||
|
insert into t2(t2f1, t2f2, t2f3) values (3, 3, '3');
|
||||||
|
insert into t2(t2f1, t2f2, t2f3) values (104, 104, '104');
|
||||||
|
insert into t2(t2f1, t2f2, t2f3) values (105, 105, '105');
|
||||||
|
insert into t2(t2f1, t2f2, t2f3) values (106, 106, '106');
|
||||||
|
|
||||||
|
set count on;
|
||||||
|
|
||||||
|
select x.*, y.*, UDR40_frac( mod(t2f1,100) / 100.000)
|
||||||
|
from v1 x, v2 y
|
||||||
|
where x.t1f1 = y.t2f2
|
||||||
|
and UDR40_frac( mod(t2f1,100) / 100.000) < 0.03
|
||||||
|
;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
Records affected: 0
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=4.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
1092
tests/bugs/core_0039_test.py
Normal file
1092
tests/bugs/core_0039_test.py
Normal file
File diff suppressed because it is too large
Load Diff
150
tests/bugs/core_0053_test.py
Normal file
150
tests/bugs/core_0053_test.py
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0053
|
||||||
|
# title: FIRST 1 vs ORDER DESC vs explicit plan (ODS11)
|
||||||
|
# decription:
|
||||||
|
# Test uses pre-created database which has several procedures for analyzing performance by with the help of MON$ tables.
|
||||||
|
# Performance results are gathered in the table STAT_LOG, each odd run will save mon$ counters with "-" sign and next
|
||||||
|
# (even) run will save them with "+" -- see SP_GATHER_STAT.
|
||||||
|
# Aggegation of results is done in the view V_AGG_STAT (negative values relate to start, positive to the end of measure,
|
||||||
|
# difference between them means performance expenses which we want to evaluate).
|
||||||
|
# NOTE. Before each new measure we have to set generator G_GATHER_STAT to zero in order to make it produce proper values
|
||||||
|
# starting with 1 (odd --> NEGATIVE sign for counters). This is done in SP_TRUNCATE_STAT.
|
||||||
|
#
|
||||||
|
# :::::::::::::::::::::::::::::::::::::::: NB ::::::::::::::::::::::::::::::::::::
|
||||||
|
# 18.08.2020. FB 4.x has incompatible behaviour with all previous versions since build 4.0.0.2131 (06-aug-2020):
|
||||||
|
# statement 'alter sequence <seq_name> restart with 0' changes rdb$generators.rdb$initial_value to -1 thus next call
|
||||||
|
# gen_id(<seq_name>,1) will return 0 (ZERO!) rather than 1.
|
||||||
|
# See also CORE-6084 and its fix: https://github.com/FirebirdSQL/firebird/commit/23dc0c6297825b2e9006f4d5a2c488702091033d
|
||||||
|
# ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
# This is considered as *expected* and is noted in doc/README.incompatibilities.3to4.txt
|
||||||
|
#
|
||||||
|
# Because of this, it was decided to change code of SP_TRUNCATE_STAT: instead of 'alter sequence restart...' we do
|
||||||
|
# reset like this: c = gen_id(g_gather_stat, -gen_id(g_gather_stat, 0));
|
||||||
|
#
|
||||||
|
# Checked on:
|
||||||
|
# 4.0.0.2164 SS: 2.511s.
|
||||||
|
# 4.0.0.2164 CS: 2.533s.
|
||||||
|
# 3.0.7.33356 SS: 1.495s.
|
||||||
|
# 3.0.7.33356 CS: 2.865s.
|
||||||
|
# 2.5.9.27150 SC: 0.730s.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0053
|
||||||
|
# min_versions: ['2.5.1']
|
||||||
|
# versions: 2.5.1
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(from_backup='mon-stat-gathering-2_5.fbk', init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
create or alter procedure gendata as begin end;
|
||||||
|
recreate table test (F1 integer, F2 date);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create or alter procedure GenData as
|
||||||
|
declare i integer;
|
||||||
|
begin
|
||||||
|
i= 0;
|
||||||
|
while (i < 100000) do begin
|
||||||
|
insert into test(F1, F2) values (:i, 'yesterday');
|
||||||
|
i= i+1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
execute procedure gendata;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create desc index test_f1_f2 on test(F1, F2);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
execute procedure sp_truncate_stat;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
-- #################### MEASURE-1 #################
|
||||||
|
|
||||||
|
execute procedure sp_gather_stat; ------- catch statistics BEFORE measured statement(s)
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set plan on;
|
||||||
|
select first 1 f1
|
||||||
|
from test t
|
||||||
|
where t.f1=17 and f2 <= 'today'
|
||||||
|
plan (T order test_f1_f2)
|
||||||
|
order by F1 desc, F2 desc;
|
||||||
|
set plan off;
|
||||||
|
|
||||||
|
execute procedure sp_gather_stat; ------- catch statistics BEFORE measured statement(s)
|
||||||
|
commit;
|
||||||
|
|
||||||
|
-- #################### MEASURE-2 #################
|
||||||
|
|
||||||
|
|
||||||
|
execute procedure sp_gather_stat; ------- catch statistics BEFORE measured statement(s)
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set plan on;
|
||||||
|
select first 1 f1
|
||||||
|
from test t
|
||||||
|
where t.f1=17 and f2 <= 'today'
|
||||||
|
plan (t order test_f1_f2 index (test_f1_f2))
|
||||||
|
order by F1 desc, F2 desc;
|
||||||
|
set plan off;
|
||||||
|
|
||||||
|
execute procedure sp_gather_stat; ------- catch statistics BEFORE measured statement(s)
|
||||||
|
commit;
|
||||||
|
|
||||||
|
-- #################### ANALYZING RESULTS #################
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
select
|
||||||
|
iif( idx_1 / idx_2 > max_ratio, 'PLAN (T ORDER <idx_name>) is slow! Ratio > ' || max_ratio,
|
||||||
|
iif( idx_2 / idx_1 > max_ratio, 'PLAN (T ORDER <idx_name> INDEX(<idx_name>)) is slow! Ratio > '|| max_ratio,
|
||||||
|
'PERFORMANCE IS THE SAME.'
|
||||||
|
)
|
||||||
|
) result
|
||||||
|
from (
|
||||||
|
select
|
||||||
|
cast(min(idx_1) as double precision) as idx_1,
|
||||||
|
cast( min(idx_2) as double precision) as idx_2,
|
||||||
|
3.00 as max_ratio
|
||||||
|
from (
|
||||||
|
select iif(rowset=1, indexed_reads, null) idx_1, iif(rowset=2, indexed_reads, null) idx_2
|
||||||
|
from v_agg_stat
|
||||||
|
) g
|
||||||
|
);
|
||||||
|
-- Difference of indexed reads that is reported by MON$ tables:
|
||||||
|
-- on 2.5 = {5, 5}, on 3.0 = {5, 3} ==> ratio 3.00 should be always enough.
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
PLAN (T ORDER TEST_F1_F2)
|
||||||
|
F1 17
|
||||||
|
PLAN (T ORDER TEST_F1_F2 INDEX (TEST_F1_F2))
|
||||||
|
F1 17
|
||||||
|
RESULT PERFORMANCE IS THE SAME.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.1')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
69
tests/bugs/core_0058_test.py
Normal file
69
tests/bugs/core_0058_test.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0058
|
||||||
|
# title: WHERE CURRENT OF doesn't work
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0058
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('line: [0-9]+, col: [0-9]+', '')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
-- NB: changed expected value of SQLSTATE to actual. See comment in git:
|
||||||
|
-- "Prevent stack trace (line/column info) from overriding the real error's SQLSTATE", 30-apr-2016
|
||||||
|
-- https://github.com/FirebirdSQL/firebird/commit/d1d8b36a07d4f11d98d2c8ec16fb8ec073da442b // FB 4.0
|
||||||
|
-- https://github.com/FirebirdSQL/firebird/commit/849bfac745bc9158e9ef7990f5d52913f8b72f02 // FB 3.0
|
||||||
|
-- https://github.com/FirebirdSQL/firebird/commit/b9d4142c4ed1fdf9b7c633edc7b2425f7b93eed0 // FB 2.5
|
||||||
|
-- See also letter from dimitr, 03-may-2016 19:24.
|
||||||
|
|
||||||
|
recreate table test (a integer not null, constraint test_pk primary key (a));
|
||||||
|
insert into test (a) values (1);
|
||||||
|
insert into test (a) values (2);
|
||||||
|
insert into test (a) values (3);
|
||||||
|
insert into test (a) values (4);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create procedure test_upd(d integer) as
|
||||||
|
declare c cursor for (
|
||||||
|
select a from test
|
||||||
|
);
|
||||||
|
begin
|
||||||
|
open c;
|
||||||
|
update test set a = a + :d
|
||||||
|
where current of c;
|
||||||
|
close c;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
execute procedure test_upd (2);
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 22000
|
||||||
|
no current record for fetch operation
|
||||||
|
-At procedure 'TEST_UPD'
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
50
tests/bugs/core_0059_test.py
Normal file
50
tests/bugs/core_0059_test.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0059
|
||||||
|
# title: Automatic not null in PK columns incomplete
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0059
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table test (a int, b float, c varchar(10), primary key (a, b, c));
|
||||||
|
commit;
|
||||||
|
insert into test(a) values(null);
|
||||||
|
insert into test(a,b) values(1,null);
|
||||||
|
insert into test(a,b,c) values(1,1,null);
|
||||||
|
insert into test default values;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 23000
|
||||||
|
validation error for column "TEST"."A", value "*** null ***"
|
||||||
|
Statement failed, SQLSTATE = 23000
|
||||||
|
validation error for column "TEST"."B", value "*** null ***"
|
||||||
|
Statement failed, SQLSTATE = 23000
|
||||||
|
validation error for column "TEST"."C", value "*** null ***"
|
||||||
|
Statement failed, SQLSTATE = 23000
|
||||||
|
validation error for column "TEST"."A", value "*** null ***"
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
59
tests/bugs/core_0063_test.py
Normal file
59
tests/bugs/core_0063_test.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0063
|
||||||
|
# title: Sequence of commands crash FB server
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0063
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(charset='WIN1252', sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set bail on;
|
||||||
|
|
||||||
|
create domain d_descricao_30000_nn as varchar(30000) not null collate win_ptbr;
|
||||||
|
create table movimento( complemento d_descricao_30000_nn );
|
||||||
|
|
||||||
|
insert into movimento values ('');
|
||||||
|
insert into movimento values ('1234567890');
|
||||||
|
insert into movimento values ('');
|
||||||
|
|
||||||
|
create domain d_text_blob as blob sub_type text collate win_ptbr;
|
||||||
|
|
||||||
|
alter table movimento add complemento2 d_text_blob;
|
||||||
|
|
||||||
|
update movimento set complemento2 = complemento;
|
||||||
|
|
||||||
|
alter table movimento drop complemento, add complemento d_text_blob;
|
||||||
|
|
||||||
|
drop domain d_descricao_30000_nn;
|
||||||
|
|
||||||
|
update movimento set complemento = complemento2;
|
||||||
|
set list on;
|
||||||
|
select 'OK' as result from rdb$database;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
RESULT OK
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
46
tests/bugs/core_0070_test.py
Normal file
46
tests/bugs/core_0070_test.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0070
|
||||||
|
# title: Expression index regression since 2.0a3
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0070
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table t1 (col1 varchar(36));
|
||||||
|
commit;
|
||||||
|
insert into t1 select lower(uuid_to_char(gen_uuid())) from rdb$types rows 100;
|
||||||
|
commit;
|
||||||
|
create index idx1 on t1 computed by (upper(col1));
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set planonly;
|
||||||
|
select * from t1 where upper(col1) = '1';
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
PLAN (T1 INDEX (IDX1))
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
76
tests/bugs/core_0076_test.py
Normal file
76
tests/bugs/core_0076_test.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0076
|
||||||
|
# title: Invalid ROW_COUNT variable value after DELETE
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0076
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create or alter procedure test_del as begin end;
|
||||||
|
|
||||||
|
recreate table test (
|
||||||
|
a integer not null,
|
||||||
|
constraint test_pk primary key (a)
|
||||||
|
);
|
||||||
|
insert into test (a) values (1);
|
||||||
|
insert into test (a) values (2);
|
||||||
|
insert into test (a) values (3);
|
||||||
|
insert into test (a) values (4);
|
||||||
|
insert into test (a) values (5);
|
||||||
|
insert into test (a) values (6);
|
||||||
|
insert into test (a) values (7);
|
||||||
|
insert into test (a) values (8);
|
||||||
|
insert into test (a) values (9);
|
||||||
|
insert into test (a) values (10);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
select count(*) as cnt from test where a between 4 and 7;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create or alter procedure test_del (l integer, r integer) returns (rc integer) as
|
||||||
|
begin
|
||||||
|
delete from test where a between :l and :r;
|
||||||
|
rc = row_count;
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
execute procedure test_del (4, 7);
|
||||||
|
select * from test;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
CNT 4
|
||||||
|
RC 4
|
||||||
|
A 1
|
||||||
|
A 2
|
||||||
|
A 3
|
||||||
|
A 8
|
||||||
|
A 9
|
||||||
|
A 10
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
201
tests/bugs/core_0085_test.py
Normal file
201
tests/bugs/core_0085_test.py
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0085
|
||||||
|
# title: Query with not in (select) returns wrong result
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0085
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
-- Results are OK since 2.1.7 up to 4.0.0
|
||||||
|
-- Confirmed wrong result on 1.5.6
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create or alter procedure tst1
|
||||||
|
returns (packages integer)
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
packages=1;
|
||||||
|
suspend;
|
||||||
|
packages=2;
|
||||||
|
suspend;
|
||||||
|
end^
|
||||||
|
set term ;^
|
||||||
|
|
||||||
|
recreate table frrates1 (
|
||||||
|
frrates1 integer not null,
|
||||||
|
packages integer,
|
||||||
|
primary key(frrates1)
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create index idx_frrates1_packages on frrates1 (packages);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate table schedpkgs1 (
|
||||||
|
schedpkgs1 integer not null,
|
||||||
|
schedule integer,
|
||||||
|
frrates1 integer,
|
||||||
|
primary key (schedpkgs1)
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create index idx_schedpkgs1_schedule on schedpkgs1 (schedule);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into frrates1 (frrates1, packages) values (11, 1);
|
||||||
|
insert into frrates1 (frrates1, packages) values (12, 2);
|
||||||
|
/* second record is essential (must exist in tst1) */
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into schedpkgs1 (schedpkgs1, schedule, frrates1) values(21, 16651,11);
|
||||||
|
insert into schedpkgs1 (schedpkgs1, schedule, frrates1) values(22, 16651,null);
|
||||||
|
/* important null value */
|
||||||
|
commit;
|
||||||
|
|
||||||
|
|
||||||
|
set count on;
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
-- sub-query to be used later in sub-select,
|
||||||
|
-- correctly uses frrates1 primary key index fr index (rdb$primary121),
|
||||||
|
-- correctly returns (1)
|
||||||
|
|
||||||
|
select fr.packages
|
||||||
|
from schedpkgs1 sp
|
||||||
|
join frrates1 fr on fr.frrates1=sp.frrates1
|
||||||
|
where sp.schedule = 16651;
|
||||||
|
|
||||||
|
-- 1. results from stored procedure (1, 2),
|
||||||
|
-- filtered out by sub-select query (1),
|
||||||
|
-- expected results -- (2),
|
||||||
|
-- ib5.6 correctly uses frrates1 primary key index fr index (rdb$primary121),
|
||||||
|
-- ib5.6 returns correct results (2),
|
||||||
|
-- problem -- fb1.5.3/2.0rc2 does not return anything,
|
||||||
|
-- problem -- fb1.5.3/2.0rc2 uses wrong frrates1
|
||||||
|
-- index fr index (idx_frrates1_packages)
|
||||||
|
|
||||||
|
select packages
|
||||||
|
from tst1
|
||||||
|
where packages not in (select fr.packages
|
||||||
|
from schedpkgs1 sp
|
||||||
|
join frrates1 fr on
|
||||||
|
fr.frrates1=sp.frrates1
|
||||||
|
where sp.schedule = 16651);
|
||||||
|
|
||||||
|
-- 2a. adding additional filter in sub-select query
|
||||||
|
-- 'fr.packages>0' fb1.5.3 still uses questionable frrates1 index fr
|
||||||
|
-- index (idx_frrates1_packages) but results are as expected (2)
|
||||||
|
|
||||||
|
select packages
|
||||||
|
from tst1
|
||||||
|
where packages not in (select fr.packages
|
||||||
|
from schedpkgs1 sp
|
||||||
|
join frrates1 fr on
|
||||||
|
fr.frrates1=sp.frrates1
|
||||||
|
where sp.schedule = 16651
|
||||||
|
and fr.packages>0);
|
||||||
|
|
||||||
|
-- 2b. replacing "not in" with "<> any" will return
|
||||||
|
-- expected result and uses expected indices
|
||||||
|
|
||||||
|
select t.packages
|
||||||
|
from tst1 t
|
||||||
|
where t.packages <> all (select fr.packages
|
||||||
|
from schedpkgs1 sp
|
||||||
|
join frrates1 fr on
|
||||||
|
fr.frrates1=sp.frrates1
|
||||||
|
where sp.schedule = 16651);
|
||||||
|
|
||||||
|
-- 3. using table instead of stored procedure in main
|
||||||
|
-- query, both ib5.6 and fb1.5.3 uses questionable frrates1
|
||||||
|
-- index fr index (idx_frrates1_packages),
|
||||||
|
-- and results are wrong, i.e. does not return (2)
|
||||||
|
|
||||||
|
select f2.packages
|
||||||
|
from frrates1 f2
|
||||||
|
where f2.packages not in
|
||||||
|
(
|
||||||
|
select fr.packages
|
||||||
|
from schedpkgs1 sp
|
||||||
|
join frrates1 fr on
|
||||||
|
fr.frrates1=sp.frrates1
|
||||||
|
where sp.schedule = 16651
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
-- 4a. adding the same additional filter
|
||||||
|
-- 'fr.packages>0' in sub-select query,
|
||||||
|
-- incorrect results in ib5.6 (no results) (fr index
|
||||||
|
-- (rdb$primary121,idx_frrates1_packages)),
|
||||||
|
-- correct results in fb1.5.3 (returns 2)
|
||||||
|
-- fb1.5.3 still uses questionable frrates1 index fr
|
||||||
|
-- index (idx_frrates1_packages)
|
||||||
|
|
||||||
|
|
||||||
|
select f2.packages
|
||||||
|
from frrates1 f2
|
||||||
|
where f2.packages not in
|
||||||
|
(
|
||||||
|
select fr.packages
|
||||||
|
from schedpkgs1 sp
|
||||||
|
join frrates1 fr on
|
||||||
|
fr.frrates1=sp.frrates1
|
||||||
|
where sp.schedule = 16651
|
||||||
|
and fr.packages > 0
|
||||||
|
);
|
||||||
|
|
||||||
|
-- 4b. and again, the same query with <> any instead
|
||||||
|
-- not in works correctly
|
||||||
|
|
||||||
|
select f2.packages
|
||||||
|
from frrates1 f2
|
||||||
|
where f2.packages <> all
|
||||||
|
(
|
||||||
|
select fr.packages
|
||||||
|
from schedpkgs1 sp
|
||||||
|
join frrates1 fr on
|
||||||
|
fr.frrates1=sp.frrates1
|
||||||
|
where sp.schedule = 16651
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
PACKAGES 1
|
||||||
|
Records affected: 1
|
||||||
|
PACKAGES 2
|
||||||
|
Records affected: 1
|
||||||
|
PACKAGES 2
|
||||||
|
Records affected: 1
|
||||||
|
PACKAGES 2
|
||||||
|
Records affected: 1
|
||||||
|
PACKAGES 2
|
||||||
|
Records affected: 1
|
||||||
|
PACKAGES 2
|
||||||
|
Records affected: 1
|
||||||
|
PACKAGES 2
|
||||||
|
Records affected: 1
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
45
tests/bugs/core_0086_test.py
Normal file
45
tests/bugs/core_0086_test.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0086
|
||||||
|
# title: Index bug
|
||||||
|
# decription: Can not fetch the data when Index is use
|
||||||
|
# tracker_id: CORE-86
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.1
|
||||||
|
# qmid: bugs.core_86
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(from_backup='core86.fbk', init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """Select * from YLK A where PH = '0021'
|
||||||
|
and HPBH = '492'
|
||||||
|
and CD = 'MG'
|
||||||
|
and JLDW = 'JIAN'
|
||||||
|
and JZDW = 'DUN'
|
||||||
|
and CK = '8K'
|
||||||
|
and HW = '1.8'
|
||||||
|
and SH='1.81';"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """ID_YLK PH HPBH CD JLDW JZDW CK HW SH
|
||||||
|
============ ==================== ============ ==================== ====== ====== ================ ============ =====================
|
||||||
|
110 0021 492 MG JIAN DUN 8K 1.8 1.81000
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
84
tests/bugs/core_0088_test.py
Normal file
84
tests/bugs/core_0088_test.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0088
|
||||||
|
# title: Join on diffrent datatypes
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-88
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: bugs.core_88
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """CREATE TABLE TEST_A (
|
||||||
|
ID INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
SNUM CHAR(10) UNIQUE
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE TEST_B (
|
||||||
|
ID INTEGER NOT NULL PRIMARY KEY,
|
||||||
|
NUM NUMERIC(15,2) UNIQUE
|
||||||
|
);
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
INSERT INTO TEST_A (ID, SNUM) VALUES (1, '01');
|
||||||
|
INSERT INTO TEST_A (ID, SNUM) VALUES (2, '02');
|
||||||
|
INSERT INTO TEST_A (ID, SNUM) VALUES (3, '03');
|
||||||
|
INSERT INTO TEST_A (ID, SNUM) VALUES (5, '05');
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
INSERT INTO TEST_B (ID, NUM) VALUES (1, 1);
|
||||||
|
INSERT INTO TEST_B (ID, NUM) VALUES (2, 2);
|
||||||
|
INSERT INTO TEST_B (ID, NUM) VALUES (3, 3);
|
||||||
|
INSERT INTO TEST_B (ID, NUM) VALUES (4, 4);
|
||||||
|
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """SET PLAN ON;
|
||||||
|
|
||||||
|
SELECT * FROM test_b WHERE num NOT IN (SELECT snum FROM test_a) ;
|
||||||
|
|
||||||
|
SELECT * FROM test_b WHERE num IN (SELECT snum FROM test_a) ;
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
PLAN (TEST_A NATURAL)
|
||||||
|
PLAN (TEST_A NATURAL)
|
||||||
|
PLAN (TEST_B NATURAL)
|
||||||
|
|
||||||
|
ID NUM
|
||||||
|
============ =====================
|
||||||
|
4 4.00
|
||||||
|
|
||||||
|
|
||||||
|
PLAN (TEST_A NATURAL)
|
||||||
|
PLAN (TEST_B NATURAL)
|
||||||
|
|
||||||
|
ID NUM
|
||||||
|
============ =====================
|
||||||
|
1 1.00
|
||||||
|
2 2.00
|
||||||
|
3 3.00
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
328
tests/bugs/core_0089_test.py
Normal file
328
tests/bugs/core_0089_test.py
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0089
|
||||||
|
# title: Using where params in SUM return incorrect results
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0089
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
-- DDL and data are based on text file (report) that is attached to ticket.
|
||||||
|
-- No difference between FB 1.5.6 and 4.0.0 found.
|
||||||
|
-- Added PK on table categorygroup and index "schemacategories(typecol)"
|
||||||
|
-- after analyzing text of queries - it seems to me that such indices
|
||||||
|
-- does exist on real schema.
|
||||||
|
|
||||||
|
recreate table schemacategories(
|
||||||
|
schemanr int
|
||||||
|
,catnr int
|
||||||
|
,typecol int
|
||||||
|
,depnr int
|
||||||
|
,ownedby int
|
||||||
|
,heritage char(4)
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
create index sch_cat_typecol on schemacategories(typecol);
|
||||||
|
|
||||||
|
recreate table categorygroup(
|
||||||
|
id int primary key
|
||||||
|
,parent int
|
||||||
|
,depnr int
|
||||||
|
,heritage char(4)
|
||||||
|
,activecol int
|
||||||
|
,displaytype int
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into schemacategories values(11, 472, 10, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 463, 10, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 464, 10, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 497, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 501, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 296, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 265, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 496, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 500, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 498, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 499, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 494, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 261, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 495, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 413, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 244, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 488, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 492, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 249, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 493, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 247, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 502, 6, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 251, 6, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 490, 6, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 367, 6, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 489, 6, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 505, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 506, 4, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 507, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 508, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 509, 5, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 491, 6, 1, 10000175, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 450, 1, 1, 10000090, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 485, 1, 1, 10000090, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 486, 1, 1, 10000090, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 451, 1, 1, 10000090, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 452, 1, 1, 10000090, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 453, 1, 1, 10000090, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 454, 1, 1, 10000090, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 455, 1, 1, 10000090, 'TRUE');
|
||||||
|
insert into schemacategories values(11, 456, 1, 1, 10000090, 'TRUE');
|
||||||
|
commit;
|
||||||
|
|
||||||
|
|
||||||
|
insert into categorygroup values(1,0,1,'TRUE',1,1);
|
||||||
|
insert into categorygroup values(2,0,1,'TRUE',1,2);
|
||||||
|
insert into categorygroup values(3,0,1,'TRUE',1,2);
|
||||||
|
insert into categorygroup values(4,0,1,'TRUE',1,3);
|
||||||
|
insert into categorygroup values(5,0,1,'TRUE',1,3);
|
||||||
|
insert into categorygroup values(6,0,1,'TRUE',1,3);
|
||||||
|
insert into categorygroup values(7,0,1,'TRUE',1,2);
|
||||||
|
insert into categorygroup values(8,5,1,'TRUE',0,3);
|
||||||
|
insert into categorygroup values(9,0,1,'TRUE',1,2);
|
||||||
|
insert into categorygroup values(10,0,1,'TRUE',1,2);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
select sc.schemanr,sc.catnr,sc.typecol,cg.id
|
||||||
|
from schemacategories sc, categorygroup cg
|
||||||
|
where sc.schemanr = 11 and sc.typecol = cg.id
|
||||||
|
order by sc.catnr;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 244
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 247
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 249
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 251
|
||||||
|
TYPECOL 6
|
||||||
|
ID 6
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 261
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 265
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 296
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 367
|
||||||
|
TYPECOL 6
|
||||||
|
ID 6
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 413
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 450
|
||||||
|
TYPECOL 1
|
||||||
|
ID 1
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 451
|
||||||
|
TYPECOL 1
|
||||||
|
ID 1
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 452
|
||||||
|
TYPECOL 1
|
||||||
|
ID 1
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 453
|
||||||
|
TYPECOL 1
|
||||||
|
ID 1
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 454
|
||||||
|
TYPECOL 1
|
||||||
|
ID 1
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 455
|
||||||
|
TYPECOL 1
|
||||||
|
ID 1
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 456
|
||||||
|
TYPECOL 1
|
||||||
|
ID 1
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 463
|
||||||
|
TYPECOL 10
|
||||||
|
ID 10
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 464
|
||||||
|
TYPECOL 10
|
||||||
|
ID 10
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 472
|
||||||
|
TYPECOL 10
|
||||||
|
ID 10
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 485
|
||||||
|
TYPECOL 1
|
||||||
|
ID 1
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 486
|
||||||
|
TYPECOL 1
|
||||||
|
ID 1
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 488
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 489
|
||||||
|
TYPECOL 6
|
||||||
|
ID 6
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 490
|
||||||
|
TYPECOL 6
|
||||||
|
ID 6
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 491
|
||||||
|
TYPECOL 6
|
||||||
|
ID 6
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 492
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 493
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 494
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 495
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 496
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 497
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 498
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 499
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 500
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 501
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 502
|
||||||
|
TYPECOL 6
|
||||||
|
ID 6
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 505
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 506
|
||||||
|
TYPECOL 4
|
||||||
|
ID 4
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 507
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 508
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
|
||||||
|
SCHEMANR 11
|
||||||
|
CATNR 509
|
||||||
|
TYPECOL 5
|
||||||
|
ID 5
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
50
tests/bugs/core_0091_test.py
Normal file
50
tests/bugs/core_0091_test.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0091
|
||||||
|
# title: Recreate and self-referencing indexes
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-91
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.1
|
||||||
|
# qmid: bugs.core_91
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """recreate table t2 (
|
||||||
|
i integer not null primary key,
|
||||||
|
p integer references t2(i) on delete set null
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """select * from t2;
|
||||||
|
insert into t2 values (1, null);
|
||||||
|
delete from t2 where i=1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate table t2 (
|
||||||
|
i integer not null primary key,
|
||||||
|
p integer references t2(i) on delete set null
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
select * from t2;
|
||||||
|
insert into t2 values (1, null);
|
||||||
|
delete from t2 where i=1;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.execute()
|
||||||
|
|
53
tests/bugs/core_0099_test.py
Normal file
53
tests/bugs/core_0099_test.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0099
|
||||||
|
# title: Strange/Inconsistent query results
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-99
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.1
|
||||||
|
# qmid: bugs.core_99
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table T1 (F1 char(4), F2 char(4));
|
||||||
|
create index T1_F1 on T1 (F1);
|
||||||
|
|
||||||
|
insert into T1 (F1, F2) values ('001', '001');
|
||||||
|
insert into T1 (F1, F2) values ('002', '002');
|
||||||
|
insert into T1 (F1, F2) values ('003', '003');
|
||||||
|
insert into T1 (F1, F2) values ('004', '004');
|
||||||
|
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=1, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """select * from t1 where f1 = 3;
|
||||||
|
select * from t1 where f2 = 3;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """F1 F2
|
||||||
|
====== ======
|
||||||
|
003 003
|
||||||
|
|
||||||
|
F1 F2
|
||||||
|
====== ======
|
||||||
|
003 003
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
111
tests/bugs/core_0101_test.py
Normal file
111
tests/bugs/core_0101_test.py
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0101
|
||||||
|
# title: JOIN the same table - problem with alias names
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0101
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
-- Confirmed wrong result on WI-V1.5.6.5026, all above wirks fine.
|
||||||
|
recreate table test(id int);
|
||||||
|
insert into test values(1);
|
||||||
|
insert into test values(-1);
|
||||||
|
insert into test values(-2);
|
||||||
|
insert into test values(2);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
--set plan on;
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
select *
|
||||||
|
from (
|
||||||
|
select test.id a_id, b.id as b_id
|
||||||
|
from test test
|
||||||
|
join test b on test.id = b.id
|
||||||
|
) order by 1,2
|
||||||
|
;
|
||||||
|
|
||||||
|
create index test_id on test(id);
|
||||||
|
|
||||||
|
select *
|
||||||
|
from (
|
||||||
|
select test.id a_id, b.id as b_id
|
||||||
|
from test test
|
||||||
|
join test b on test.id = b.id
|
||||||
|
) order by 1,2
|
||||||
|
;
|
||||||
|
|
||||||
|
select *
|
||||||
|
from (
|
||||||
|
select test.id a_id, b.id as b_id
|
||||||
|
from (select id from test order by id) test
|
||||||
|
join (select id from test order by id) b on test.id = b.id
|
||||||
|
) order by 1,2
|
||||||
|
;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
A_ID -2
|
||||||
|
B_ID -2
|
||||||
|
|
||||||
|
A_ID -1
|
||||||
|
B_ID -1
|
||||||
|
|
||||||
|
A_ID 1
|
||||||
|
B_ID 1
|
||||||
|
|
||||||
|
A_ID 2
|
||||||
|
B_ID 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A_ID -2
|
||||||
|
B_ID -2
|
||||||
|
|
||||||
|
A_ID -1
|
||||||
|
B_ID -1
|
||||||
|
|
||||||
|
A_ID 1
|
||||||
|
B_ID 1
|
||||||
|
|
||||||
|
A_ID 2
|
||||||
|
B_ID 2
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
A_ID -2
|
||||||
|
B_ID -2
|
||||||
|
|
||||||
|
A_ID -1
|
||||||
|
B_ID -1
|
||||||
|
|
||||||
|
A_ID 1
|
||||||
|
B_ID 1
|
||||||
|
|
||||||
|
A_ID 2
|
||||||
|
B_ID 2
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
50
tests/bugs/core_0104_test.py
Normal file
50
tests/bugs/core_0104_test.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0104
|
||||||
|
# title: Dropping and recreating a table in the same txn disables PK
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-104
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.5.3
|
||||||
|
# qmid: bugs.core_104-250
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.3
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table test (acolumn int not null primary key);
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """SET AUTODDL OFF;
|
||||||
|
|
||||||
|
drop table test;
|
||||||
|
create table test (acolumn int not null primary key);
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test values (1);
|
||||||
|
insert into test values (1);
|
||||||
|
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """Statement failed, SQLSTATE = 23000
|
||||||
|
violation of PRIMARY or UNIQUE KEY constraint "INTEG_4" on table "TEST"
|
||||||
|
-Problematic key value is ("ACOLUMN" = 1)
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.3')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
67
tests/bugs/core_0115_test.py
Normal file
67
tests/bugs/core_0115_test.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0115
|
||||||
|
# title: bug with ALL keyword
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0115
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table test (i int not null);
|
||||||
|
|
||||||
|
insert into test values (2);
|
||||||
|
insert into test values (3);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set plan on;
|
||||||
|
|
||||||
|
set count on;
|
||||||
|
select * from test where 1 > all(select i from test);
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
alter table test add constraint test_pk primary key(i) using index test_pk;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
select * from test where i > all(select i from test);
|
||||||
|
select * from test where i > 0 and i > all(select i from test where i > 0);
|
||||||
|
|
||||||
|
set count off;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
PLAN (TEST NATURAL)
|
||||||
|
PLAN (TEST NATURAL)
|
||||||
|
Records affected: 0
|
||||||
|
|
||||||
|
PLAN (TEST NATURAL)
|
||||||
|
PLAN (TEST NATURAL)
|
||||||
|
Records affected: 0
|
||||||
|
|
||||||
|
PLAN (TEST INDEX (TEST_PK))
|
||||||
|
PLAN (TEST INDEX (TEST_PK))
|
||||||
|
Records affected: 0
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
51
tests/bugs/core_0116_test.py
Normal file
51
tests/bugs/core_0116_test.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0116
|
||||||
|
# title: CREATE TABLE - no blob for external
|
||||||
|
# decription: CREATE TABLE - blob not allow for external tables
|
||||||
|
#
|
||||||
|
# Dependencies:
|
||||||
|
# CREATE DATABASE
|
||||||
|
# CREATE TABLE
|
||||||
|
# tracker_id: CORE-116
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_116-250
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
-- Untill build 3.0.0.31721 STDERR was:
|
||||||
|
-- -Data type BLOB is not supported ... field '<Missing arg #3 - possibly status vector overflow>'
|
||||||
|
-- Since WI-T3.0.0.31733 STDERR became normal - contains name of field.
|
||||||
|
-- See correction in 'expected_stderr' secsion (23.03.2015).
|
||||||
|
create table ext_log external file '$(DATABASE_LOCATION)z.dat' (F1 INT, F2 BLOB SUB_TYPE TEXT);
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = HY004
|
||||||
|
unsuccessful metadata update
|
||||||
|
-CREATE TABLE EXT_LOG failed
|
||||||
|
-SQL error code = -607
|
||||||
|
-Invalid command
|
||||||
|
-Data type BLOB is not supported for EXTERNAL TABLES. Relation 'EXT_LOG', field 'F2'
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
77
tests/bugs/core_0117_test.py
Normal file
77
tests/bugs/core_0117_test.py
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0117
|
||||||
|
# title: Expression evaluation not supported on LEFT JOIN
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0117
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
-- Output is fine in WI-V1.5.6.5026 and all above.
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
recreate table t1(
|
||||||
|
id numeric( 18, 0) not null,
|
||||||
|
id2 numeric( 18,0),
|
||||||
|
date1 date,
|
||||||
|
constraint pk_t1 primary key (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
recreate table t2(
|
||||||
|
id numeric( 18, 0) not null,
|
||||||
|
id2 numeric( 18,0),
|
||||||
|
date1 date,
|
||||||
|
constraint pk_t2 primary key (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
insert into t1(id, id2, date1) values (1, 1, '10/13/2003');
|
||||||
|
insert into t1(id, id2, date1) values (2, 2, '09/13/2003');
|
||||||
|
insert into t2(id, id2, date1) values (1, 1, '09/13/2003');
|
||||||
|
commit;
|
||||||
|
|
||||||
|
--executing the following query in isql returns the error
|
||||||
|
--message "expression evaluation not supported" after
|
||||||
|
--retrieving the
|
||||||
|
--first row.
|
||||||
|
|
||||||
|
|
||||||
|
select t_1.id2, t_1.date1 as d1, t_2.date1 as d2
|
||||||
|
from t1 t_1
|
||||||
|
left join t2 t_2 on t_1.id2=t_2.id2
|
||||||
|
where
|
||||||
|
extract(month from t_1.date1)
|
||||||
|
<>
|
||||||
|
extract(month from t_2.date1)
|
||||||
|
;
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
ID2 1
|
||||||
|
D1 2003-10-13
|
||||||
|
D2 2003-09-13
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
75
tests/bugs/core_0119_test.py
Normal file
75
tests/bugs/core_0119_test.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0119
|
||||||
|
# title: numeric div in dialect 3 mangles data
|
||||||
|
# decription:
|
||||||
|
# NOTE. Results for FB 4.0 become differ from old one. Discussed with Alex, 30.10.2019.
|
||||||
|
# Precise value of 70000 / 1.95583 is: 35790.431683735296 (checked on https://www.wolframalpha.com )
|
||||||
|
# Section 'expected-stdout' was adjusted to be match for results that are issued in recent FB.
|
||||||
|
# Discuss with Alex see in e-mail, letters 30.10.2019.
|
||||||
|
# Checked on:
|
||||||
|
# 4.0.0.1635 SS: 0.909s.
|
||||||
|
# 3.0.5.33182 SS: 0.740s.
|
||||||
|
# 2.5.9.27146 SC: 0.212s.
|
||||||
|
#
|
||||||
|
# 21.06.2020, 4.0.0.2068 (see also: CORE-6337):
|
||||||
|
# changed subtype from 0 to 1 for cast (-70000 as numeric (18,5)) / cast (1.95583 as numeric (18,5))
|
||||||
|
# (after discuss with dimitr, letter 21.06.2020 08:43).
|
||||||
|
#
|
||||||
|
# 25.06.2020, 4.0.0.2076: changed types in SQLDA from numeric to int128 // after discuss with Alex about CORE-6342.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0119
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 4.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 4.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('^((?!(sqltype|DIV_RESULT)).)*$', ''), ('[ \t]+', ' '), ('.*alias.*', '')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
set sqlda_display on;
|
||||||
|
select cast (-70000 as numeric (18,5)) / cast (1.95583 as numeric (18,5)) as div_result_1 from rdb$database;
|
||||||
|
|
||||||
|
-- doc\\sql.extensions\\README.data_types:
|
||||||
|
-- - QUANTIZE - has two DECFLOAT arguments. The returned value is first argument scaled using
|
||||||
|
-- second value as a pattern. For example QUANTIZE(1234, 9.999) returns 1234.000.
|
||||||
|
|
||||||
|
select QUANTIZE(cast(-70000 as decfloat(34)) / cast (1.95583 as decfloat(34)), 9.9999999999) as div_result_2 from rdb$database;
|
||||||
|
select (-4611686018427387904)/-0.5 div_result_3 from rdb$database;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
01: sqltype: 32752 INT128 scale: -10 subtype: 1 len: 16
|
||||||
|
DIV_RESULT_1 -35790.4316837352
|
||||||
|
|
||||||
|
01: sqltype: 32762 DECFLOAT(34) scale: 0 subtype: 0 len: 16
|
||||||
|
DIV_RESULT_2 -35790.4316837353
|
||||||
|
|
||||||
|
01: sqltype: 32752 INT128 scale: -1 subtype: 0 len: 16
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 22003
|
||||||
|
arithmetic exception, numeric overflow, or string truncation
|
||||||
|
-numeric value is out of range
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=4.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
102
tests/bugs/core_0142_test.py
Normal file
102
tests/bugs/core_0142_test.py
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0142
|
||||||
|
# title: index breaks = ANY result
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0142
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
-- Confirmed wrong output on WI-V1.5.6.5026.
|
||||||
|
-- Since 2.0.0 works fine.
|
||||||
|
|
||||||
|
recreate view v_test(k) as select 1 k from rdb$database;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate table customers (
|
||||||
|
cnum integer,
|
||||||
|
cname char(10),
|
||||||
|
city char(10),
|
||||||
|
rating integer,
|
||||||
|
snum integer
|
||||||
|
);
|
||||||
|
|
||||||
|
recreate view v_test(cnum, cname, city, rating, snum) as
|
||||||
|
select *
|
||||||
|
from customers c
|
||||||
|
where not c.rating = any
|
||||||
|
(select r.rating
|
||||||
|
from customers r
|
||||||
|
where r.city = 'san jose');
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into customers values (2001, 'hoffman', 'london', 100, 1001);
|
||||||
|
insert into customers values (2002, 'giovanni', 'rome', 200, 1003);
|
||||||
|
insert into customers values (2003, 'lui', 'san jose', 200, 1002);
|
||||||
|
insert into customers values (2004, 'grass', 'berlin', 300, 1002);
|
||||||
|
insert into customers values (2006, 'clemens', 'london', null, 1001);
|
||||||
|
insert into customers values (2008, 'cisneros', 'san jose', 300, 1007);
|
||||||
|
insert into customers values (2007, 'pereira', 'rome', 100, 1004);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
select * from v_test order by cnum;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create index byrating on customers (rating);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
select * from v_test order by cnum;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
CNUM 2001
|
||||||
|
CNAME hoffman
|
||||||
|
CITY london
|
||||||
|
RATING 100
|
||||||
|
SNUM 1001
|
||||||
|
|
||||||
|
CNUM 2007
|
||||||
|
CNAME pereira
|
||||||
|
CITY rome
|
||||||
|
RATING 100
|
||||||
|
SNUM 1004
|
||||||
|
|
||||||
|
CNUM 2001
|
||||||
|
CNAME hoffman
|
||||||
|
CITY london
|
||||||
|
RATING 100
|
||||||
|
SNUM 1001
|
||||||
|
|
||||||
|
CNUM 2007
|
||||||
|
CNAME pereira
|
||||||
|
CITY rome
|
||||||
|
RATING 100
|
||||||
|
SNUM 1004
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
85
tests/bugs/core_0143_test.py
Normal file
85
tests/bugs/core_0143_test.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0143
|
||||||
|
# title: Using where params in SUM return incorrect results
|
||||||
|
# decription:
|
||||||
|
# 30.10.2019. NB: new datatype in FB 4.0 was introduces: numeric(38,0).
|
||||||
|
# It can lead to additional ident of values when we show them in form "SET LIST ON",
|
||||||
|
# so we have to ignore all internal spaces - see added 'substitution' section below.
|
||||||
|
# Checked on:
|
||||||
|
# 4.0.0.1635 SS: 1.061s.
|
||||||
|
# 3.0.5.33182 SS: 0.754s.
|
||||||
|
# 2.5.9.27146 SC: 0.190s.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0143
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('[ \t]+', ' ')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table yeardata
|
||||||
|
(
|
||||||
|
id integer not null,
|
||||||
|
ayear integer,
|
||||||
|
avalue numeric( 18, 2),
|
||||||
|
constraint pk_yeardata primary key (id)
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into yeardata(id, ayear, avalue) values (1, 2005, 3.40);
|
||||||
|
insert into yeardata(id, ayear, avalue) values (2, 2005, 6.60);
|
||||||
|
insert into yeardata(id, ayear, avalue) values (3, 2004, 5.20);
|
||||||
|
insert into yeardata(id, ayear, avalue) values (4, 2004, 5.80);
|
||||||
|
insert into yeardata(id, ayear, avalue) values (5, 2004, 5.00);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
select
|
||||||
|
sum(case when ayear = 2004 then avalue else null end) as avalue_2004_1
|
||||||
|
,sum(case when ayear = 2005 then avalue else null end) as avalue_2005_1
|
||||||
|
from yeardata;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
execute block returns( avalue_2004_2 numeric( 18, 2), avalue_2005_2 numeric( 18, 2)) as
|
||||||
|
begin
|
||||||
|
execute statement
|
||||||
|
(
|
||||||
|
'select
|
||||||
|
sum(case when ayear = ? then avalue else null end)
|
||||||
|
,sum(case when ayear = ? then avalue else null end)
|
||||||
|
from yeardata'
|
||||||
|
) ( 2004, 2005 )
|
||||||
|
into avalue_2004_2, avalue_2005_2;
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
AVALUE_2004_1 16.00
|
||||||
|
AVALUE_2005_1 10.00
|
||||||
|
AVALUE_2004_2 16.00
|
||||||
|
AVALUE_2005_2 10.00
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
56
tests/bugs/core_0148_test.py
Normal file
56
tests/bugs/core_0148_test.py
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0148
|
||||||
|
# title: SELECT '1' UNION SELECT '12'
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0148
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
-- Confirmed: runtime error on WI-V1.5.6.5026:
|
||||||
|
-- -SQL error code = -104
|
||||||
|
-- -Invalid command
|
||||||
|
-- -Data type unknown
|
||||||
|
|
||||||
|
recreate table test_a(x int);
|
||||||
|
recreate table test_b(y int);
|
||||||
|
|
||||||
|
insert into test_a values(9999999);
|
||||||
|
insert into test_b values(888888);
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
select '1' || a.x as result
|
||||||
|
from test_a a
|
||||||
|
union
|
||||||
|
select '12' || b.y
|
||||||
|
from test_b b
|
||||||
|
;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
RESULT 12888888
|
||||||
|
RESULT 19999999
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
236
tests/bugs/core_0149_test.py
Normal file
236
tests/bugs/core_0149_test.py
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0149
|
||||||
|
# title: Left joining views with null fails
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0149
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
-- Initial comment by johnsparrowuk, 19/Mar/04 12:00 AM:
|
||||||
|
recreate view currentpeople(k) as select 1 as k from rdb$database;
|
||||||
|
recreate view finishedpeople(k) as select 1 as k from rdb$database;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate table mytable (
|
||||||
|
person varchar(20) not null,
|
||||||
|
status int not null, primary key (person,status)
|
||||||
|
);
|
||||||
|
|
||||||
|
recreate view currentpeople(person) as
|
||||||
|
select distinct person as person
|
||||||
|
from mytable where status = 1;
|
||||||
|
|
||||||
|
recreate view finishedpeople(person) as
|
||||||
|
select distinct person as person
|
||||||
|
from mytable where status = 2;
|
||||||
|
|
||||||
|
insert into mytable values ('john',1);
|
||||||
|
insert into mytable values ('john',2);
|
||||||
|
insert into mytable values ('fred',1);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
-- This works fine: fred-null, john-john
|
||||||
|
select *
|
||||||
|
from currentpeople c
|
||||||
|
left join finishedpeople f on c.person = f.person
|
||||||
|
order by c.person, f.person
|
||||||
|
;
|
||||||
|
|
||||||
|
-- This is as expected too: john-john
|
||||||
|
select *
|
||||||
|
from currentpeople c
|
||||||
|
left join finishedpeople f
|
||||||
|
on c.person = f.person where f.person = 'john'
|
||||||
|
order by c.person, f.person
|
||||||
|
;
|
||||||
|
|
||||||
|
-- WHATS HAPPENING HERE????? fred-null, JOHN-NULL where does the john-null come from???
|
||||||
|
select *
|
||||||
|
from currentpeople c
|
||||||
|
left join finishedpeople f on c.person = f.person
|
||||||
|
where f.person is null
|
||||||
|
order by c.person, f.person
|
||||||
|
;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
--#################################################
|
||||||
|
|
||||||
|
-- Alice F. Bird added a comment - 14/Jun/06 09:32 AM
|
||||||
|
recreate table test (
|
||||||
|
id int not null,
|
||||||
|
name varchar(15),
|
||||||
|
pid integer
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into test(id, name, pid) values(1, 'Car', null);
|
||||||
|
insert into test(id, name, pid) values(2, 'Engine', 1);
|
||||||
|
insert into test(id, name, pid) values(3, 'Body', 1);
|
||||||
|
insert into test(id, name, pid) values(4, 'Oil Filter',2);
|
||||||
|
insert into test(id, name, pid) values(5, 'Air Filter',2);
|
||||||
|
insert into test(id, name, pid) values(6, 'Door Left', 3);
|
||||||
|
insert into test(id, name, pid) values(7, 'Door Right',3);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
-- This query issued WRONG result on 1.5.6
|
||||||
|
-- (because first data source - 'TEST' - has not alias)
|
||||||
|
select *
|
||||||
|
from test
|
||||||
|
left outer join test t2
|
||||||
|
on test.pid=t2.id
|
||||||
|
order by test.id, t2.id
|
||||||
|
;
|
||||||
|
|
||||||
|
-- This works fine:
|
||||||
|
select *
|
||||||
|
from test t1
|
||||||
|
left outer join test t2
|
||||||
|
on t1.pid=t2.id
|
||||||
|
order by t1.id, t2.id
|
||||||
|
;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
PERSON fred
|
||||||
|
PERSON <null>
|
||||||
|
|
||||||
|
PERSON john
|
||||||
|
PERSON john
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PERSON john
|
||||||
|
PERSON john
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PERSON fred
|
||||||
|
PERSON <null>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ID 1
|
||||||
|
NAME Car
|
||||||
|
PID <null>
|
||||||
|
ID <null>
|
||||||
|
NAME <null>
|
||||||
|
PID <null>
|
||||||
|
|
||||||
|
ID 2
|
||||||
|
NAME Engine
|
||||||
|
PID 1
|
||||||
|
ID 1
|
||||||
|
NAME Car
|
||||||
|
PID <null>
|
||||||
|
|
||||||
|
ID 3
|
||||||
|
NAME Body
|
||||||
|
PID 1
|
||||||
|
ID 1
|
||||||
|
NAME Car
|
||||||
|
PID <null>
|
||||||
|
|
||||||
|
ID 4
|
||||||
|
NAME Oil Filter
|
||||||
|
PID 2
|
||||||
|
ID 2
|
||||||
|
NAME Engine
|
||||||
|
PID 1
|
||||||
|
|
||||||
|
ID 5
|
||||||
|
NAME Air Filter
|
||||||
|
PID 2
|
||||||
|
ID 2
|
||||||
|
NAME Engine
|
||||||
|
PID 1
|
||||||
|
|
||||||
|
ID 6
|
||||||
|
NAME Door Left
|
||||||
|
PID 3
|
||||||
|
ID 3
|
||||||
|
NAME Body
|
||||||
|
PID 1
|
||||||
|
|
||||||
|
ID 7
|
||||||
|
NAME Door Right
|
||||||
|
PID 3
|
||||||
|
ID 3
|
||||||
|
NAME Body
|
||||||
|
PID 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ID 1
|
||||||
|
NAME Car
|
||||||
|
PID <null>
|
||||||
|
ID <null>
|
||||||
|
NAME <null>
|
||||||
|
PID <null>
|
||||||
|
|
||||||
|
ID 2
|
||||||
|
NAME Engine
|
||||||
|
PID 1
|
||||||
|
ID 1
|
||||||
|
NAME Car
|
||||||
|
PID <null>
|
||||||
|
|
||||||
|
ID 3
|
||||||
|
NAME Body
|
||||||
|
PID 1
|
||||||
|
ID 1
|
||||||
|
NAME Car
|
||||||
|
PID <null>
|
||||||
|
|
||||||
|
ID 4
|
||||||
|
NAME Oil Filter
|
||||||
|
PID 2
|
||||||
|
ID 2
|
||||||
|
NAME Engine
|
||||||
|
PID 1
|
||||||
|
|
||||||
|
ID 5
|
||||||
|
NAME Air Filter
|
||||||
|
PID 2
|
||||||
|
ID 2
|
||||||
|
NAME Engine
|
||||||
|
PID 1
|
||||||
|
|
||||||
|
ID 6
|
||||||
|
NAME Door Left
|
||||||
|
PID 3
|
||||||
|
ID 3
|
||||||
|
NAME Body
|
||||||
|
PID 1
|
||||||
|
|
||||||
|
ID 7
|
||||||
|
NAME Door Right
|
||||||
|
PID 3
|
||||||
|
ID 3
|
||||||
|
NAME Body
|
||||||
|
PID 1
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
84
tests/bugs/core_0165_test.py
Normal file
84
tests/bugs/core_0165_test.py
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0165
|
||||||
|
# title: Query using VIEW with UNION causes crash
|
||||||
|
# decription:
|
||||||
|
# Original test see im:
|
||||||
|
# https://github.com/FirebirdSQL/fbtcs/blob/master/GTCS/tests/CF_ISQL_24.script
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0165
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate view v_test1 ( id, x ) as select 1, 2 from rdb$database;
|
||||||
|
recreate view v_test2 ( id, x ) as select 1, 2 from rdb$database;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate table test1 (
|
||||||
|
id int not null,
|
||||||
|
x int not null);
|
||||||
|
|
||||||
|
recreate table test2 (
|
||||||
|
id int not null,
|
||||||
|
y int not null);
|
||||||
|
|
||||||
|
recreate view v_test1 ( id, x ) as
|
||||||
|
select id, x
|
||||||
|
from test1
|
||||||
|
union
|
||||||
|
select id, x
|
||||||
|
from test1;
|
||||||
|
|
||||||
|
recreate view v_test2 ( id, y ) as
|
||||||
|
select id, y
|
||||||
|
from test2
|
||||||
|
union
|
||||||
|
select id, y
|
||||||
|
from test2;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test1 values(1, 123);
|
||||||
|
insert into test1 values(2, 456);
|
||||||
|
insert into test2 values(3, 151);
|
||||||
|
insert into test2 values(2, 456);
|
||||||
|
insert into test2 values(1, 123);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
--set plan on;
|
||||||
|
select i.id as id_1, i.x as x, j.id as id_2, j.y as y
|
||||||
|
from v_test1 i, v_test2 j
|
||||||
|
where i.id = j.id
|
||||||
|
and j.y = (select max(x.y) from v_test2 x)
|
||||||
|
;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
ID_1 2
|
||||||
|
X 456
|
||||||
|
ID_2 2
|
||||||
|
Y 456
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
136
tests/bugs/core_0166_test.py
Normal file
136
tests/bugs/core_0166_test.py
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0166
|
||||||
|
# title: cannot specify PLAN in UPDATE statement
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0166
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table company(id int not null primary key, contact_id int, company_name varchar(60));
|
||||||
|
recreate table contact(id int not null primary key using index contact_id, contact_name varchar(60));
|
||||||
|
alter table company add constraint company_fk foreign key(contact_id) references contact(id);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into contact values(1, '+784956253581, Vovan');
|
||||||
|
insert into contact values(2, '+375172223217, Shurik');
|
||||||
|
insert into contact values(3, '+380442057337, Vitalik');
|
||||||
|
|
||||||
|
insert into company values(100, 1, 'Pepsico, Inc.');
|
||||||
|
insert into company values(101, 1, '');
|
||||||
|
insert into company values(102, 2, 'Balaha, Inc.');
|
||||||
|
insert into company values(103, 2, '');
|
||||||
|
insert into company values(104, 2, null);
|
||||||
|
insert into company values(105, 3, null);
|
||||||
|
insert into company values(106, 3, 'Firebird Foundation');
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
select c.*
|
||||||
|
from company c order by c.id;
|
||||||
|
|
||||||
|
set plan on;
|
||||||
|
set count on;
|
||||||
|
|
||||||
|
update company c set c.company_name =
|
||||||
|
( select k.contact_name
|
||||||
|
from contact k
|
||||||
|
where k.id = c.contact_id
|
||||||
|
PLAN (K INDEX (CONTACT_ID))
|
||||||
|
)
|
||||||
|
where c.company_name is null or c.company_name = ''
|
||||||
|
PLAN (C NATURAL)
|
||||||
|
;
|
||||||
|
|
||||||
|
set plan off;
|
||||||
|
set count off;
|
||||||
|
|
||||||
|
select c.*
|
||||||
|
from company c order by c.id;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
ID 100
|
||||||
|
CONTACT_ID 1
|
||||||
|
COMPANY_NAME Pepsico, Inc.
|
||||||
|
|
||||||
|
ID 101
|
||||||
|
CONTACT_ID 1
|
||||||
|
COMPANY_NAME
|
||||||
|
|
||||||
|
ID 102
|
||||||
|
CONTACT_ID 2
|
||||||
|
COMPANY_NAME Balaha, Inc.
|
||||||
|
|
||||||
|
ID 103
|
||||||
|
CONTACT_ID 2
|
||||||
|
COMPANY_NAME
|
||||||
|
|
||||||
|
ID 104
|
||||||
|
CONTACT_ID 2
|
||||||
|
COMPANY_NAME <null>
|
||||||
|
|
||||||
|
ID 105
|
||||||
|
CONTACT_ID 3
|
||||||
|
COMPANY_NAME <null>
|
||||||
|
|
||||||
|
ID 106
|
||||||
|
CONTACT_ID 3
|
||||||
|
COMPANY_NAME Firebird Foundation
|
||||||
|
|
||||||
|
PLAN (K INDEX (CONTACT_ID))
|
||||||
|
PLAN (C NATURAL)
|
||||||
|
Records affected: 4
|
||||||
|
|
||||||
|
ID 100
|
||||||
|
CONTACT_ID 1
|
||||||
|
COMPANY_NAME Pepsico, Inc.
|
||||||
|
|
||||||
|
ID 101
|
||||||
|
CONTACT_ID 1
|
||||||
|
COMPANY_NAME +784956253581, Vovan
|
||||||
|
|
||||||
|
ID 102
|
||||||
|
CONTACT_ID 2
|
||||||
|
COMPANY_NAME Balaha, Inc.
|
||||||
|
|
||||||
|
ID 103
|
||||||
|
CONTACT_ID 2
|
||||||
|
COMPANY_NAME +375172223217, Shurik
|
||||||
|
|
||||||
|
ID 104
|
||||||
|
CONTACT_ID 2
|
||||||
|
COMPANY_NAME +375172223217, Shurik
|
||||||
|
|
||||||
|
ID 105
|
||||||
|
CONTACT_ID 3
|
||||||
|
COMPANY_NAME +380442057337, Vitalik
|
||||||
|
|
||||||
|
ID 106
|
||||||
|
CONTACT_ID 3
|
||||||
|
COMPANY_NAME Firebird Foundation
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
69
tests/bugs/core_0185_test.py
Normal file
69
tests/bugs/core_0185_test.py
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0185
|
||||||
|
# title: DB crashes if trigger BU deletes own row
|
||||||
|
# decription:
|
||||||
|
# Ortiginal test:
|
||||||
|
# https://github.com/FirebirdSQL/fbtcs/blob/master/GTCS/tests/CF_ISQL_28.script
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0185
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create table test (id integer not null);
|
||||||
|
commit;
|
||||||
|
set term ^ ;
|
||||||
|
create trigger test_bu for test active before update position 0 as
|
||||||
|
begin
|
||||||
|
delete from test where id=old.id;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ; ^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test values (1);
|
||||||
|
insert into test values (2);
|
||||||
|
insert into test values (3);
|
||||||
|
insert into test values (4);
|
||||||
|
insert into test values (5);
|
||||||
|
insert into test values (6);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
update test set id=-1 where id=1;
|
||||||
|
rollback;
|
||||||
|
set list on;
|
||||||
|
select count(*) from test;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
COUNT 6
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 22000
|
||||||
|
no current record for fetch operation
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
164
tests/bugs/core_0188_test.py
Normal file
164
tests/bugs/core_0188_test.py
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0188
|
||||||
|
# title: trigger on view with union receive nulls
|
||||||
|
# decription:
|
||||||
|
# Passed on: WI-V3.0.0.32487, WI-T4.0.0.141 -- works fine.
|
||||||
|
# On WI-V2.5.6.27001 issues wrong result thus min_version (for now) is 3.0.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0188
|
||||||
|
# min_versions: ['3.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set bail on;
|
||||||
|
set width ctx_name 30;
|
||||||
|
set width ctx_val 10;
|
||||||
|
|
||||||
|
recreate view v_ctx_data as
|
||||||
|
select mon$variable_name as ctx_name, mon$variable_value as ctx_val
|
||||||
|
from mon$context_variables c
|
||||||
|
where mon$attachment_id = current_connection or mon$transaction_id = current_transaction;
|
||||||
|
|
||||||
|
recreate view v_test as select 1 k from rdb$database;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate table test_a (id int);
|
||||||
|
recreate table test_b (id int);
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate view v_test(id, row_from_table_b)
|
||||||
|
as
|
||||||
|
select id, cast(0 as int)
|
||||||
|
from test_a a
|
||||||
|
where not exists (select * from test_b b where b.id = a.id)
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select id, cast(1 as int)
|
||||||
|
from test_b;
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create or alter procedure sp_zap_context_vars as
|
||||||
|
declare ctx_ssn int;
|
||||||
|
declare ctx_name varchar(80);
|
||||||
|
begin
|
||||||
|
for
|
||||||
|
select mon$attachment_id, mon$variable_name as ctx_name
|
||||||
|
from mon$context_variables c
|
||||||
|
where mon$attachment_id = current_connection or mon$transaction_id = current_transaction
|
||||||
|
into ctx_ssn, ctx_name
|
||||||
|
do
|
||||||
|
execute statement
|
||||||
|
'rdb$set_context('
|
||||||
|
|| iif(ctx_ssn is not null, '''USER_SESSION''', '''USER_TRANSACTION''')
|
||||||
|
|| ', '''
|
||||||
|
|| ctx_name
|
||||||
|
|| ''', null )'
|
||||||
|
;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
|
||||||
|
create trigger v_test_bu for v_test active before update position 0 as
|
||||||
|
declare o int;
|
||||||
|
begin
|
||||||
|
rdb$set_context('USER_SESSION','trigger_sees_old_id', old.id);
|
||||||
|
rdb$set_context('USER_SESSION','trigger_sees_old_of_b1', old.row_from_table_b);
|
||||||
|
rdb$set_context('USER_SESSION','trigger_sees_new_id', new.id);
|
||||||
|
rdb$set_context('USER_SESSION','trigger_sees_new_of_b', new.row_from_table_b);
|
||||||
|
if (new.row_from_table_b = 1) then
|
||||||
|
begin
|
||||||
|
rdb$set_context('USER_SESSION','trigger_sees_old_of_b2', old.row_from_table_b);
|
||||||
|
if (old.row_from_table_b = 0) then
|
||||||
|
begin
|
||||||
|
rdb$set_context('USER_SESSION','trigger_sees_old_of_b3', old.row_from_table_b);
|
||||||
|
execute statement ( 'insert into test_b(id) values(?)') (new.id);
|
||||||
|
execute statement ( 'delete from test_a where id = ?' ) (new.id);
|
||||||
|
rdb$set_context('USER_SESSION','trigger_DID_its_job', new.id);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
delete from test_b
|
||||||
|
where id = old.id;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
|
||||||
|
insert into test_a(id) values(1);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
select * from v_test; -- will return one record based on data in table test_a
|
||||||
|
|
||||||
|
-- must insert row into test_b and remove row with the same id from test_a:
|
||||||
|
execute procedure sp_zap_context_vars;
|
||||||
|
select * from v_ctx_data;
|
||||||
|
|
||||||
|
update v_test set row_from_table_b = 1 where id = 1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set count on;
|
||||||
|
select * from test_a;
|
||||||
|
select * from test_b;
|
||||||
|
select * from v_ctx_data;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
ID 1
|
||||||
|
ROW_FROM_TABLE_B 0
|
||||||
|
Records affected: 0
|
||||||
|
ID 1
|
||||||
|
Records affected: 1
|
||||||
|
|
||||||
|
CTX_NAME trigger_DID_its_job
|
||||||
|
CTX_VAL 1
|
||||||
|
|
||||||
|
CTX_NAME trigger_sees_new_id
|
||||||
|
CTX_VAL 1
|
||||||
|
|
||||||
|
CTX_NAME trigger_sees_new_of_b
|
||||||
|
CTX_VAL 1
|
||||||
|
|
||||||
|
CTX_NAME trigger_sees_old_id
|
||||||
|
CTX_VAL 1
|
||||||
|
|
||||||
|
CTX_NAME trigger_sees_old_of_b1
|
||||||
|
CTX_VAL 0
|
||||||
|
|
||||||
|
CTX_NAME trigger_sees_old_of_b2
|
||||||
|
CTX_VAL 0
|
||||||
|
|
||||||
|
CTX_NAME trigger_sees_old_of_b3
|
||||||
|
CTX_VAL 0
|
||||||
|
|
||||||
|
|
||||||
|
Records affected: 7
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
55
tests/bugs/core_0190_test.py
Normal file
55
tests/bugs/core_0190_test.py
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0190
|
||||||
|
# title: SYSDBA can grant non existent roles
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0190
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('Statement failed, SQLSTATE = HY000', ''), ('record not found for user:.*', '')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create or alter user tmp$c0196 password '123';
|
||||||
|
commit;
|
||||||
|
grant no_such_role to tmp$c0196;
|
||||||
|
commit;
|
||||||
|
set count on;
|
||||||
|
set list on;
|
||||||
|
select * from rdb$user_privileges where rdb$user = upper('tmp$c0196') rows 1;
|
||||||
|
commit;
|
||||||
|
drop user tmp$c0196;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
Records affected: 0
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-GRANT failed
|
||||||
|
-SQL role NO_SUCH_ROLE does not exist
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
120
tests/bugs/core_0195_test.py
Normal file
120
tests/bugs/core_0195_test.py
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0195
|
||||||
|
# title: Bugcheck 291
|
||||||
|
# decription:
|
||||||
|
# tracker_id:
|
||||||
|
# min_versions: ['2.0.7']
|
||||||
|
# versions: 2.0.7
|
||||||
|
# qmid: bugs.core_0195
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.0.7
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create table tbl_bugcheck291
|
||||||
|
(
|
||||||
|
ID integer NOT NULL PRIMARY KEY,
|
||||||
|
DATA integer
|
||||||
|
);
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into tbl_bugcheck291 (id, data) values (1,100);
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create trigger bu_tbl_bugcheck291 for tbl_bugcheck291
|
||||||
|
before update
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
if(new.data is not null) then
|
||||||
|
begin
|
||||||
|
if(new.data<110) then
|
||||||
|
begin
|
||||||
|
update tbl_bugcheck291 x set x.data=new.data+1 where x.id=new.id;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
update tbl_bugcheck291 set data=105 where id=1;
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
update tbl_bugcheck291 set data=105 where id=1;
|
||||||
|
|
||||||
|
/*FB2.5: internal Firebird consistency check (cannot find record back version (291), file: vio.cpp line: 5014).*/
|
||||||
|
update tbl_bugcheck291 set data=105 where id=1;
|
||||||
|
|
||||||
|
/*internal Firebird consistency check (can't continue after bugcheck).*/
|
||||||
|
update tbl_bugcheck291 set data=105 where id=1;
|
||||||
|
update tbl_bugcheck291 set data=105 where id=1;
|
||||||
|
update tbl_bugcheck291 set data=105 where id=1;
|
||||||
|
update tbl_bugcheck291 set data=105 where id=1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
create table "TBL_BUGCHECK291B"
|
||||||
|
(
|
||||||
|
"DATA" integer,
|
||||||
|
"FLAG" integer
|
||||||
|
);
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create trigger "TRG_BUGCHECK291B" for "TBL_BUGCHECK291B"
|
||||||
|
active before update position 1
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
if (new.Flag = 16 and new.Data = 1) then begin
|
||||||
|
update tbl_bugcheck291b set Data = 2 where Flag = 46;
|
||||||
|
update tbl_bugcheck291b set Data = 3 where Flag = 46;
|
||||||
|
end
|
||||||
|
if (new.Flag = 46 and new.Data = 2) then begin
|
||||||
|
update tbl_bugcheck291b set Data = 4 where Flag = 14;
|
||||||
|
update tbl_bugcheck291b set Data = 5 where Flag = 15;
|
||||||
|
end
|
||||||
|
if (new.Flag = 14 and new.Data = 4) then begin
|
||||||
|
update tbl_bugcheck291b set Data = 6 where Flag = 46;
|
||||||
|
end
|
||||||
|
if (new.Flag = 15 and new.Data = 5) then begin
|
||||||
|
update tbl_bugcheck291b set Data = 7 where Flag = 46;
|
||||||
|
end
|
||||||
|
if (new.Flag = 46 and new.Data = 3) then begin
|
||||||
|
update tbl_bugcheck291b set Data = 8 where Flag = 46;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into tbl_bugcheck291b(Flag) values(14);
|
||||||
|
insert into tbl_bugcheck291b(Flag) values(15);
|
||||||
|
insert into tbl_bugcheck291b(Flag) values(16);
|
||||||
|
insert into tbl_bugcheck291b(Flag) values(46);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
update tbl_bugcheck291b set Data=1 where Flag = 16;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.0.7')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.execute()
|
||||||
|
|
117
tests/bugs/core_0198_test.py
Normal file
117
tests/bugs/core_0198_test.py
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0198
|
||||||
|
# title: wrong order by in table join storedproc
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0198
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table my_table
|
||||||
|
(
|
||||||
|
k varchar(10) not null,
|
||||||
|
d1 integer,
|
||||||
|
d2 integer,
|
||||||
|
v1 varchar(10),
|
||||||
|
primary key (k)
|
||||||
|
);
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create or alter procedure select_me returns(
|
||||||
|
data varchar(10)
|
||||||
|
) as
|
||||||
|
begin
|
||||||
|
data = 'one';
|
||||||
|
suspend;
|
||||||
|
data = 'two';
|
||||||
|
suspend;
|
||||||
|
data = 'three';
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into my_table values ('one', 1, 99, 'zz');
|
||||||
|
insert into my_table values ('two', 2, 98, 'yy');
|
||||||
|
insert into my_table values ('three', 3, 97, 'xx');
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
select *
|
||||||
|
from my_table t join select_me p on (t.k = p.data)
|
||||||
|
order by t.d1
|
||||||
|
;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create index i1 on my_table(d1);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
select *
|
||||||
|
from my_table t join select_me p on (t.k = p.data)
|
||||||
|
order by t.d1
|
||||||
|
;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
K one
|
||||||
|
D1 1
|
||||||
|
D2 99
|
||||||
|
V1 zz
|
||||||
|
DATA one
|
||||||
|
|
||||||
|
K two
|
||||||
|
D1 2
|
||||||
|
D2 98
|
||||||
|
V1 yy
|
||||||
|
DATA two
|
||||||
|
|
||||||
|
K three
|
||||||
|
D1 3
|
||||||
|
D2 97
|
||||||
|
V1 xx
|
||||||
|
DATA three
|
||||||
|
|
||||||
|
K one
|
||||||
|
D1 1
|
||||||
|
D2 99
|
||||||
|
V1 zz
|
||||||
|
DATA one
|
||||||
|
|
||||||
|
K two
|
||||||
|
D1 2
|
||||||
|
D2 98
|
||||||
|
V1 yy
|
||||||
|
DATA two
|
||||||
|
|
||||||
|
K three
|
||||||
|
D1 3
|
||||||
|
D2 97
|
||||||
|
V1 xx
|
||||||
|
DATA three
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
51
tests/bugs/core_0200_test.py
Normal file
51
tests/bugs/core_0200_test.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0200
|
||||||
|
# title: Empty column names with aggregate funcs
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-200
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_200
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """select (select count(1) from rdb$database) from rdb$database ;
|
||||||
|
select (select avg(1) from rdb$database) from rdb$database ;
|
||||||
|
select (select sum(1) from rdb$database) from rdb$database ;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """ COUNT
|
||||||
|
=====================
|
||||||
|
1
|
||||||
|
|
||||||
|
|
||||||
|
AVG
|
||||||
|
=====================
|
||||||
|
1
|
||||||
|
|
||||||
|
|
||||||
|
SUM
|
||||||
|
=====================
|
||||||
|
1
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
160
tests/bugs/core_0203_test.py
Normal file
160
tests/bugs/core_0203_test.py
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0203
|
||||||
|
# title: CREATE VIEW ignores PLAN
|
||||||
|
# decription:
|
||||||
|
# Test verifies that:
|
||||||
|
# 1. "PLAN <...>" clause inside view DLL is always ignored and actual plan will be one of following:
|
||||||
|
# 1.1. That is specified explicitly by client who runs a query to this view;
|
||||||
|
# 1.2. If no explicitly specified plan that optimizer will be allowed to choose that.
|
||||||
|
# 2. One may to specify PLAN on client side and it *WILL* be taken in account.
|
||||||
|
#
|
||||||
|
# ::: NOTE :::
|
||||||
|
# Suppose that some view contains explicitly specified PLAN NATURAL it its DDL.
|
||||||
|
# If underlying query became suitable to be run with PLAN INDEX (e.g. such index was added to the table)
|
||||||
|
# then this 'PLAN NATURAL' will be IGNORED until it is explicitly specified in the client query.
|
||||||
|
# See below example #4 for view v_test1 defined as "select * from ... plan (t natural)".
|
||||||
|
#
|
||||||
|
# Checked on:
|
||||||
|
# 4.0.0.1743 SS: 1.781s.
|
||||||
|
# 4.0.0.1714 CS: 6.500s.
|
||||||
|
# 3.0.6.33236 SS: 1.313s.
|
||||||
|
# 3.0.6.33236 CS: 1.891s.
|
||||||
|
# 2.5.9.27149 SC: 1.047s.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0203
|
||||||
|
# min_versions: ['2.5']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('[ ]+', ' ')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set bail on;
|
||||||
|
|
||||||
|
recreate view v_test4 as select 1 x from rdb$database;
|
||||||
|
recreate view v_test3 as select 1 x from rdb$database;
|
||||||
|
recreate view v_test2 as select 1 x from rdb$database;
|
||||||
|
recreate view v_test1 as select 1 x from rdb$database;
|
||||||
|
|
||||||
|
recreate table test(x int, y int);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test(x,y) select rand()*100, rand()*10000 from rdb$types,rdb$types rows 10000;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create index test_x_asc on test(x);
|
||||||
|
create descending index test_x_desc on test(x);
|
||||||
|
|
||||||
|
create index test_y_x on test(y, x);
|
||||||
|
create index test_x_y on test(x, y);
|
||||||
|
|
||||||
|
create index test_sum_x_y on test computed by (x+y);
|
||||||
|
create descending index test_sub_x_y on test computed by (x-y);
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate view v_test1 as select * from test t where x = 0 plan (t natural);
|
||||||
|
recreate view v_test2 as select * from test t where x = 0;
|
||||||
|
recreate view v_test3 as select * from test t where x = 0 plan (t index(test_x_desc));
|
||||||
|
recreate view v_test4 as select * from v_test3;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
|
||||||
|
set planonly;
|
||||||
|
--set echo on;
|
||||||
|
|
||||||
|
select * from test t where x = 0 plan (t natural); -- 1
|
||||||
|
|
||||||
|
select * from v_test1 v1; -- 2
|
||||||
|
|
||||||
|
select * from v_test1 v2; -- 3
|
||||||
|
|
||||||
|
select * from v_test1 v1 where v1.x = 0 plan (v1 natural); -- 4
|
||||||
|
|
||||||
|
select * from v_test2 v2 where v2.x = 0 plan (v2 natural); -- 5
|
||||||
|
|
||||||
|
select * from v_test1 v1 where v1.x = 0 PLAN (V1 INDEX (TEST_X_DESC)) ; -- 6
|
||||||
|
|
||||||
|
select * from v_test2 v2 where v2.x = 0 PLAN (V2 INDEX (TEST_X_DESC)) ; -- 7
|
||||||
|
|
||||||
|
select * from v_test1 v1 where v1.x = 50 and v1.y = 5000 PLAN (V1 INDEX (test_x_y)) ; -- 8
|
||||||
|
|
||||||
|
select * from v_test1 v2 where v2.x = 50 and v2.y = 5000 PLAN (V2 INDEX (test_y_x)) ; -- 9
|
||||||
|
|
||||||
|
select * from v_test1 v1 where v1.x + v1.y = 1000 PLAN (V1 INDEX (test_x_y)); -- 10
|
||||||
|
|
||||||
|
select * from v_test2 v2 where v2.x - v2.y = 1000 PLAN (V2 INDEX (test_x_y)); -- 11
|
||||||
|
|
||||||
|
select * from v_test1 v1 where v1.x + v1.y = 1000 PLAN (V1 INDEX (test_sum_x_y)); -- 12
|
||||||
|
|
||||||
|
select * from v_test2 v2 where v2.x - v2.y = 1000 PLAN (V2 INDEX (test_sub_x_y)); -- 13
|
||||||
|
|
||||||
|
-- NB: here optimizer will use index __NOT__ from view V3 DDL:
|
||||||
|
-- PLAN (V3 T INDEX (TEST_X_ASC))
|
||||||
|
select * from v_test3 v3; -- 14
|
||||||
|
|
||||||
|
select * from v_test3 v3 plan ( v3 index(test_x_y) );
|
||||||
|
|
||||||
|
-- NB: here optimizer will use index __NOT__ from view V3 DDL:
|
||||||
|
-- PLAN (V4 V_TEST3 T INDEX (TEST_X_ASC))
|
||||||
|
select * from v_test4 v4; -- 15
|
||||||
|
|
||||||
|
select * from v_test4 v4 PLAN (V4 V_TEST3 T INDEX (TEST_X_Y)); -- 16
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
PLAN (T NATURAL)
|
||||||
|
|
||||||
|
PLAN (V1 T INDEX (TEST_X_ASC))
|
||||||
|
|
||||||
|
PLAN (V2 T INDEX (TEST_X_ASC))
|
||||||
|
|
||||||
|
PLAN (V1 T NATURAL)
|
||||||
|
|
||||||
|
PLAN (V2 T NATURAL)
|
||||||
|
|
||||||
|
PLAN (V1 T INDEX (TEST_X_DESC))
|
||||||
|
|
||||||
|
PLAN (V2 T INDEX (TEST_X_DESC))
|
||||||
|
|
||||||
|
PLAN (V1 T INDEX (TEST_X_Y))
|
||||||
|
|
||||||
|
PLAN (V2 T INDEX (TEST_Y_X))
|
||||||
|
|
||||||
|
PLAN (V1 T INDEX (TEST_X_Y))
|
||||||
|
|
||||||
|
PLAN (V2 T INDEX (TEST_X_Y))
|
||||||
|
|
||||||
|
PLAN (V1 T INDEX (TEST_SUM_X_Y))
|
||||||
|
|
||||||
|
PLAN (V2 T INDEX (TEST_SUB_X_Y))
|
||||||
|
|
||||||
|
PLAN (V3 T INDEX (TEST_X_ASC))
|
||||||
|
|
||||||
|
PLAN (V3 T INDEX (TEST_X_Y))
|
||||||
|
|
||||||
|
PLAN (V4 V_TEST3 T INDEX (TEST_X_ASC))
|
||||||
|
|
||||||
|
PLAN (V4 V_TEST3 T INDEX (TEST_X_Y))
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
137
tests/bugs/core_0209_test.py
Normal file
137
tests/bugs/core_0209_test.py
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0209
|
||||||
|
# title: CHECK constraints fire twice
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0209
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [("-At trigger 'V_TEST_BIU' line.*", "-At trigger 'V_TEST_BIU' line")]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create domain dm_restricted_char as char(1) check (value in ('A','B','C', 'D','E'));
|
||||||
|
|
||||||
|
recreate table test (
|
||||||
|
id integer,
|
||||||
|
col dm_restricted_char
|
||||||
|
);
|
||||||
|
|
||||||
|
recreate view v_test as select * from test;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create trigger tab_biu for test before insert or update as
|
||||||
|
begin
|
||||||
|
new.col = upper (new.col);
|
||||||
|
end^
|
||||||
|
|
||||||
|
create trigger v_test_biu for v_test before insert or update as
|
||||||
|
begin
|
||||||
|
-- ::: NB :::
|
||||||
|
-- Since 2.0 trigger that belongs to updatable view MUST have DML
|
||||||
|
-- statement that handles underlying TABLE (this was not so in 1.5).
|
||||||
|
if ( inserting ) then
|
||||||
|
insert into test values( new.id, new.col );
|
||||||
|
else
|
||||||
|
update test set col = new.col, id = new.id
|
||||||
|
where id = old.id;
|
||||||
|
end^
|
||||||
|
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set count on;
|
||||||
|
set list on;
|
||||||
|
SET ECHO ON;
|
||||||
|
|
||||||
|
insert into v_test values (11, 'a');
|
||||||
|
insert into v_test values (12, 'b');
|
||||||
|
insert into v_test values (13, 'c');
|
||||||
|
insert into v_test values (14, 'd');
|
||||||
|
|
||||||
|
select * from test;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
update v_test set col='e' where id=11;
|
||||||
|
update v_test set col='e' where id=14;
|
||||||
|
|
||||||
|
update test set col='z' where id=12;
|
||||||
|
update v_test set col='x' where id=13;
|
||||||
|
|
||||||
|
select * from test;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
insert into v_test values (11, 'a');
|
||||||
|
Records affected: 1
|
||||||
|
insert into v_test values (12, 'b');
|
||||||
|
Records affected: 1
|
||||||
|
insert into v_test values (13, 'c');
|
||||||
|
Records affected: 1
|
||||||
|
insert into v_test values (14, 'd');
|
||||||
|
Records affected: 1
|
||||||
|
|
||||||
|
select * from test;
|
||||||
|
ID 11
|
||||||
|
COL A
|
||||||
|
ID 12
|
||||||
|
COL B
|
||||||
|
ID 13
|
||||||
|
COL C
|
||||||
|
ID 14
|
||||||
|
COL D
|
||||||
|
Records affected: 4
|
||||||
|
commit;
|
||||||
|
|
||||||
|
update v_test set col='e' where id=11;
|
||||||
|
Records affected: 1
|
||||||
|
update v_test set col='e' where id=14;
|
||||||
|
Records affected: 1
|
||||||
|
|
||||||
|
update test set col='z' where id=12;
|
||||||
|
Records affected: 0
|
||||||
|
update v_test set col='x' where id=13;
|
||||||
|
Records affected: 0
|
||||||
|
|
||||||
|
select * from test;
|
||||||
|
|
||||||
|
ID 11
|
||||||
|
COL E
|
||||||
|
ID 12
|
||||||
|
COL B
|
||||||
|
ID 13
|
||||||
|
COL C
|
||||||
|
ID 14
|
||||||
|
COL E
|
||||||
|
Records affected: 4
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 23000
|
||||||
|
validation error for column "TEST"."COL", value "Z"
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 23000
|
||||||
|
validation error for column "TEST"."COL", value "X"
|
||||||
|
-At trigger 'V_TEST_BIU' line: 8, col: 5
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
80
tests/bugs/core_0210_test.py
Normal file
80
tests/bugs/core_0210_test.py
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0210
|
||||||
|
# title: CS server crash altering SP in 2 connect
|
||||||
|
# decription:
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0210
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
# test_script_1
|
||||||
|
#---
|
||||||
|
#
|
||||||
|
# import os
|
||||||
|
# import fdb
|
||||||
|
#
|
||||||
|
# os.environ["ISC_USER"] = user_name
|
||||||
|
# os.environ["ISC_PASSWORD"] = user_password
|
||||||
|
#
|
||||||
|
# db_conn.close()
|
||||||
|
#
|
||||||
|
# stm1='''create or alter procedure sp_test as
|
||||||
|
# begin
|
||||||
|
# exit;
|
||||||
|
# end
|
||||||
|
# '''
|
||||||
|
# stm2='''create or alter procedure sp_test as
|
||||||
|
# declare x int;
|
||||||
|
# begin
|
||||||
|
# exit;
|
||||||
|
# end
|
||||||
|
# '''
|
||||||
|
#
|
||||||
|
# con1 = fdb.connect(dsn=dsn)
|
||||||
|
# con2 = fdb.connect(dsn=dsn)
|
||||||
|
#
|
||||||
|
# xtpb = ( [ fdb.isc_tpb_concurrency ] )
|
||||||
|
#
|
||||||
|
# con1.begin( tpb = xtpb )
|
||||||
|
#
|
||||||
|
# cur1=con1.cursor()
|
||||||
|
# cur2=con2.cursor()
|
||||||
|
#
|
||||||
|
# cur1.execute(stm1)
|
||||||
|
# con1.commit()
|
||||||
|
#
|
||||||
|
# con2.begin( tpb = xtpb )
|
||||||
|
# cur2.execute(stm2)
|
||||||
|
# con2.commit()
|
||||||
|
#
|
||||||
|
# con1.begin( tpb = xtpb )
|
||||||
|
# cur1.execute(stm1)
|
||||||
|
# con1.commit()
|
||||||
|
#
|
||||||
|
# con1.close()
|
||||||
|
# con2.close()
|
||||||
|
#
|
||||||
|
#---
|
||||||
|
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
@pytest.mark.xfail
|
||||||
|
def test_1(db_1):
|
||||||
|
pytest.fail("Test not IMPLEMENTED")
|
||||||
|
|
||||||
|
|
46
tests/bugs/core_0211_test.py
Normal file
46
tests/bugs/core_0211_test.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0211
|
||||||
|
# title: SELECT...HAVING...NOT IN crashes server
|
||||||
|
# decription:
|
||||||
|
# Crashed on: WI-V3.0.0.32380, WI-T4.0.0.32399, found 16-mar-2016.
|
||||||
|
# Passed on: WI-V3.0.0.32487, WI-T4.0.0.141 -- works fine.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0211
|
||||||
|
# min_versions: ['2.0']
|
||||||
|
# versions: 2.0.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.0.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('RDB\\$RELATION_ID[ ]+\\d+', 'RDB$RELATION_ID')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
select r.rdb$relation_id, count(*)
|
||||||
|
from rdb$database r
|
||||||
|
group by r.rdb$relation_id
|
||||||
|
having count(*) not in (select r2.rdb$relation_id from rdb$database r2);
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
RDB$RELATION_ID 134
|
||||||
|
COUNT 1
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.0.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
200
tests/bugs/core_0214_test.py
Normal file
200
tests/bugs/core_0214_test.py
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0214
|
||||||
|
# title: Count ( DISTINCT ... ) is too slow
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0214
|
||||||
|
# min_versions: ['2.5.5']
|
||||||
|
# versions: 2.5.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """
|
||||||
|
-- This test does following:
|
||||||
|
-- 1. Creates several tables with different number of unique values in field ID.
|
||||||
|
-- 2. Measures for each table time for two statements:
|
||||||
|
-- 2.1. select count(*) from ( select distinct id from ... )
|
||||||
|
-- vs
|
||||||
|
-- 2.2. select count(distinct id) from ...
|
||||||
|
-- 3. If time for 2.1 exceeds time for 2.2 more than <X> times - output message
|
||||||
|
-- about possible regression. After multiple runs it was found that ratio for
|
||||||
|
-- 2.1 vs 2.2 is about 1.05 ... 1.10. Constant <X> (threshold) was selected
|
||||||
|
-- to be enough for not to be "violated".
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table test1e1(id int); -- 10^1 distinct values
|
||||||
|
recreate table test1e2(id int); -- 10^2 distinct values
|
||||||
|
recreate table test1e3(id int); -- 10^3 distinct values
|
||||||
|
recreate table test1e4(id int); -- 10^4 distinct values
|
||||||
|
recreate table test1e5(id int); -- 10^5 distinct values
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create or alter view v_fill as
|
||||||
|
with recursive
|
||||||
|
r as(select 0 i from rdb$database union all select r.i+1 from r where r.i<9)
|
||||||
|
select r4.i * 10000 + r3.i * 1000 + r2.i * 100 + r1.i * 10 + r0.i as id
|
||||||
|
from r r4, r r3, r r2, r r1, r r0;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test1e1 select mod(id, 10) from v_fill;
|
||||||
|
insert into test1e2 select mod(id, 100) from v_fill;
|
||||||
|
insert into test1e3 select mod(id, 1000) from v_fill;
|
||||||
|
insert into test1e4 select mod(id, 10000) from v_fill;
|
||||||
|
insert into test1e5 select mod(id, 100000) from v_fill;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
|
||||||
|
execute block returns (
|
||||||
|
ratio_for_1e1 varchar(50)
|
||||||
|
,ratio_for_1e2 varchar(50)
|
||||||
|
,ratio_for_1e3 varchar(50)
|
||||||
|
,ratio_for_1e4 varchar(50)
|
||||||
|
,ratio_for_1e5 varchar(50)
|
||||||
|
)
|
||||||
|
as
|
||||||
|
-- ############################################
|
||||||
|
-- ############ T H R E S H O L D ########
|
||||||
|
|
||||||
|
-- Before 28.10.2015: 1.85 (changed after letter by dimitr).
|
||||||
|
-- Probably random disturbance was caused by other (concurrent) processes on test host.
|
||||||
|
-- Check with new threshold was done on: WI-V2.5.5.26942 (SC) and WI-V3.0.0.32134 (CS/SC/SS).
|
||||||
|
|
||||||
|
declare max_diff_threshold numeric(10,4) = 3.00;
|
||||||
|
|
||||||
|
-- ############################################
|
||||||
|
|
||||||
|
declare ratio_select_vs_count_1e1 numeric(10,4);
|
||||||
|
declare ratio_select_vs_count_1e2 numeric(10,4);
|
||||||
|
declare ratio_select_vs_count_1e3 numeric(10,4);
|
||||||
|
declare ratio_select_vs_count_1e4 numeric(10,4);
|
||||||
|
declare ratio_select_vs_count_1e5 numeric(10,4);
|
||||||
|
declare sel_distinct_1e1_ms int;
|
||||||
|
declare cnt_distinct_1e1_ms int;
|
||||||
|
declare sel_distinct_1e2_ms int;
|
||||||
|
declare cnt_distinct_1e2_ms int;
|
||||||
|
declare sel_distinct_1e3_ms int;
|
||||||
|
declare cnt_distinct_1e3_ms int;
|
||||||
|
declare sel_distinct_1e4_ms int;
|
||||||
|
declare cnt_distinct_1e4_ms int;
|
||||||
|
declare sel_distinct_1e5_ms int;
|
||||||
|
declare cnt_distinct_1e5_ms int;
|
||||||
|
declare n int;
|
||||||
|
declare t0 timestamp;
|
||||||
|
begin
|
||||||
|
t0='now';
|
||||||
|
select count(*) from ( select distinct id from test1e1 ) into n;
|
||||||
|
sel_distinct_1e1_ms = datediff(millisecond from t0 to cast('now' as timestamp));
|
||||||
|
|
||||||
|
t0='now';
|
||||||
|
select count(distinct id) from test1e1 into n;
|
||||||
|
cnt_distinct_1e1_ms = datediff(millisecond from t0 to cast('now' as timestamp));
|
||||||
|
|
||||||
|
ratio_select_vs_count_1e1 = 1.0000 * sel_distinct_1e1_ms / cnt_distinct_1e1_ms;
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
t0='now';
|
||||||
|
select count(*) from ( select distinct id from test1e2 ) into n;
|
||||||
|
sel_distinct_1e2_ms = datediff(millisecond from t0 to cast('now' as timestamp));
|
||||||
|
|
||||||
|
t0='now';
|
||||||
|
select count(distinct id) from test1e2 into n;
|
||||||
|
cnt_distinct_1e2_ms = datediff(millisecond from t0 to cast('now' as timestamp));
|
||||||
|
|
||||||
|
ratio_select_vs_count_1e2 = 1.0000 * sel_distinct_1e2_ms / cnt_distinct_1e2_ms;
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
t0='now';
|
||||||
|
select count(*) from ( select distinct id from test1e3 ) into n;
|
||||||
|
sel_distinct_1e3_ms = datediff(millisecond from t0 to cast('now' as timestamp));
|
||||||
|
|
||||||
|
t0='now';
|
||||||
|
select count(distinct id) from test1e3 into n;
|
||||||
|
cnt_distinct_1e3_ms = datediff(millisecond from t0 to cast('now' as timestamp));
|
||||||
|
|
||||||
|
ratio_select_vs_count_1e3 = 1.0000 * sel_distinct_1e3_ms / cnt_distinct_1e3_ms;
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
t0='now';
|
||||||
|
select count(*) from ( select distinct id from test1e4 ) into n;
|
||||||
|
sel_distinct_1e4_ms = datediff(millisecond from t0 to cast('now' as timestamp));
|
||||||
|
|
||||||
|
t0='now';
|
||||||
|
select count(distinct id) from test1e4 into n;
|
||||||
|
cnt_distinct_1e4_ms = datediff(millisecond from t0 to cast('now' as timestamp));
|
||||||
|
|
||||||
|
ratio_select_vs_count_1e4 = 1.0000 * sel_distinct_1e4_ms / cnt_distinct_1e4_ms;
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
t0='now';
|
||||||
|
select count(*) from ( select distinct id from test1e5 ) into n;
|
||||||
|
sel_distinct_1e5_ms = datediff(millisecond from t0 to cast('now' as timestamp));
|
||||||
|
|
||||||
|
t0='now';
|
||||||
|
select count(distinct id) from test1e5 into n;
|
||||||
|
cnt_distinct_1e5_ms = datediff(millisecond from t0 to cast('now' as timestamp));
|
||||||
|
|
||||||
|
ratio_select_vs_count_1e5 = 1.0000 * sel_distinct_1e5_ms / cnt_distinct_1e5_ms;
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
ratio_for_1e1 = 'Acceptable, <= ' || max_diff_threshold;
|
||||||
|
ratio_for_1e2 = 'Acceptable, <= ' || max_diff_threshold;
|
||||||
|
ratio_for_1e3 = 'Acceptable, <= ' || max_diff_threshold;
|
||||||
|
ratio_for_1e4 = 'Acceptable, <= ' || max_diff_threshold;
|
||||||
|
ratio_for_1e5 = 'Acceptable, <= ' || max_diff_threshold;
|
||||||
|
|
||||||
|
if (ratio_select_vs_count_1e1 > max_diff_threshold) then
|
||||||
|
ratio_for_1e1 = 'Regression: ratio = '||ratio_select_vs_count_1e1||' > '||max_diff_threshold;
|
||||||
|
|
||||||
|
if (ratio_select_vs_count_1e2 > max_diff_threshold) then
|
||||||
|
ratio_for_1e2 = 'Regression: ratio = '||ratio_select_vs_count_1e2||' > '||max_diff_threshold;
|
||||||
|
|
||||||
|
if (ratio_select_vs_count_1e3 > max_diff_threshold) then
|
||||||
|
ratio_for_1e3 = 'Regression: ratio = '||ratio_select_vs_count_1e3||' > '||max_diff_threshold;
|
||||||
|
|
||||||
|
if (ratio_select_vs_count_1e4 > max_diff_threshold) then
|
||||||
|
ratio_for_1e4 = 'Regression: ratio = '||ratio_select_vs_count_1e4||' > '||max_diff_threshold;
|
||||||
|
|
||||||
|
if (ratio_select_vs_count_1e5 > max_diff_threshold) then
|
||||||
|
ratio_for_1e5 = 'Regression: ratio = '||ratio_select_vs_count_1e5||' > '||max_diff_threshold;
|
||||||
|
|
||||||
|
|
||||||
|
suspend;
|
||||||
|
|
||||||
|
end
|
||||||
|
^ set term ;^
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
RATIO_FOR_1E1 Acceptable, <= 3.0000
|
||||||
|
RATIO_FOR_1E2 Acceptable, <= 3.0000
|
||||||
|
RATIO_FOR_1E3 Acceptable, <= 3.0000
|
||||||
|
RATIO_FOR_1E4 Acceptable, <= 3.0000
|
||||||
|
RATIO_FOR_1E5 Acceptable, <= 3.0000
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
62
tests/bugs/core_0216_test.py
Normal file
62
tests/bugs/core_0216_test.py
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0216
|
||||||
|
# title: Too many grants lose privileges
|
||||||
|
# decription: Issuing more than 2000 grants on any one object causes
|
||||||
|
# an internal buffer flow in generating the access
|
||||||
|
# control list that actually enforces the rights.
|
||||||
|
# tracker_id: CORE-216
|
||||||
|
# min_versions: ['2.5']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table T (PK integer);
|
||||||
|
create table LOG(PK integer);
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
# test_script_1
|
||||||
|
#---
|
||||||
|
# c = db_conn.cursor()
|
||||||
|
# # Create 4000 triggers on table T
|
||||||
|
# i = 1
|
||||||
|
# cmd = """create trigger LOGT_%d for T after insert as
|
||||||
|
# begin
|
||||||
|
# insert into log (PK) values (new.pk);
|
||||||
|
# end
|
||||||
|
# """
|
||||||
|
# while i <= 4000:
|
||||||
|
# c.execute(cmd % i)
|
||||||
|
# i += 1
|
||||||
|
# db_conn.commit()
|
||||||
|
#
|
||||||
|
# # Grants
|
||||||
|
# i = 1
|
||||||
|
# cmd = """GRANT INSERT ON LOG TO TRIGGER LOGT_%d"""
|
||||||
|
# while i <= 4000:
|
||||||
|
# try:
|
||||||
|
# c.execute(cmd % i)
|
||||||
|
# except Exception as e:
|
||||||
|
# print('Error:',e)
|
||||||
|
# i = 4000
|
||||||
|
# i += 1
|
||||||
|
# db_conn.commit()
|
||||||
|
#---
|
||||||
|
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
@pytest.mark.xfail
|
||||||
|
def test_1(db_1):
|
||||||
|
pytest.fail("Test not IMPLEMENTED")
|
||||||
|
|
||||||
|
|
76
tests/bugs/core_0223_test.py
Normal file
76
tests/bugs/core_0223_test.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0223
|
||||||
|
# title: ALTER TABLE altering to VARCHAR
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0223
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
recreate table test1(x int);
|
||||||
|
--create index test1_x on test1(x);
|
||||||
|
|
||||||
|
insert into test1 values(2000000000);
|
||||||
|
insert into test1 values(100000000);
|
||||||
|
insert into test1 values(50000000);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
select * from test1 order by x;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
alter table test1 alter x type varchar(5);
|
||||||
|
alter table test1 alter x type varchar(9);
|
||||||
|
|
||||||
|
alter table test1 alter x type varchar(11);
|
||||||
|
|
||||||
|
-- Here values must be sorted as TEXT:
|
||||||
|
select * from test1 order by x;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
X 50000000
|
||||||
|
X 100000000
|
||||||
|
X 2000000000
|
||||||
|
|
||||||
|
X 100000000
|
||||||
|
X 2000000000
|
||||||
|
X 50000000
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 42000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER TABLE TEST1 failed
|
||||||
|
-New size specified for column X must be at least 11 characters.
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 42000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER TABLE TEST1 failed
|
||||||
|
-New size specified for column X must be at least 11 characters.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
51
tests/bugs/core_0282_test.py
Normal file
51
tests/bugs/core_0282_test.py
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0282
|
||||||
|
# title: DOMAINs don't register their dependency on other objects
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-282
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: bugs.core_282-250
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table t(a int);
|
||||||
|
create domain d int check(value > (select max(a) from t));
|
||||||
|
commit;"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """drop table t;
|
||||||
|
commit;
|
||||||
|
create table u(a d);
|
||||||
|
commit;
|
||||||
|
show table u;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """A (D) INTEGER Nullable
|
||||||
|
check(value > (select max(a) from t))
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """Statement failed, SQLSTATE = 42000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-cannot delete
|
||||||
|
-COLUMN T.A
|
||||||
|
-there are 1 dependencies
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
60
tests/bugs/core_0284_test.py
Normal file
60
tests/bugs/core_0284_test.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0284
|
||||||
|
# title: Blob Comparison with constant
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-284
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_284
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """CREATE TABLE T1 (PK INTEGER NOT NULL, COL1 BLOB SUB_TYPE TEXT);
|
||||||
|
commit;
|
||||||
|
insert into T1 (PK,COL1) values (1,'text');
|
||||||
|
insert into T1 (PK,COL1) values (2,'');
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """select * from T1 where COL1 = '';
|
||||||
|
select * from T1 where COL1 = 'text';
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
PK COL1
|
||||||
|
============ =================
|
||||||
|
2 80:1
|
||||||
|
==============================================================================
|
||||||
|
COL1:
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
|
||||||
|
PK COL1
|
||||||
|
============ =================
|
||||||
|
1 80:0
|
||||||
|
==============================================================================
|
||||||
|
COL1:
|
||||||
|
text
|
||||||
|
==============================================================================
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
142
tests/bugs/core_0297_test.py
Normal file
142
tests/bugs/core_0297_test.py
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0297
|
||||||
|
# title: bug #585624 IB server stalled by simple script
|
||||||
|
# decription:
|
||||||
|
# ::: NB :::
|
||||||
|
# ### Name of original test has no any relation with actual task of this test: ###
|
||||||
|
# https://github.com/FirebirdSQL/fbtcs/blob/master/GTCS/tests/CF_ISQL_23.script
|
||||||
|
#
|
||||||
|
# Issue in original script: bug #585624 IB server stalled by simple script"
|
||||||
|
# Found in FB tracker as: http://tracker.firebirdsql.org/browse/CORE-297
|
||||||
|
# Fixed in 1.5.0
|
||||||
|
#
|
||||||
|
# Checked on: 4.0.0.1803 SS; 3.0.6.33265 SS; 2.5.9.27149 SC.
|
||||||
|
#
|
||||||
|
# tracker_id:
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('=', ''), ('[ \t]+', ' ')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(charset='ISO8859_1', sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set term ^;
|
||||||
|
create procedure group_copy (
|
||||||
|
source integer,
|
||||||
|
destination integer)
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
exit;
|
||||||
|
end^
|
||||||
|
|
||||||
|
create procedure insert_values (
|
||||||
|
cont integer,
|
||||||
|
d_group integer)
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
exit;
|
||||||
|
end^
|
||||||
|
set term ;^
|
||||||
|
|
||||||
|
create table groups (
|
||||||
|
gr_id integer not null,
|
||||||
|
gr_name varchar(40) character set iso8859_1 not null
|
||||||
|
collate de_de
|
||||||
|
);
|
||||||
|
|
||||||
|
create table test (
|
||||||
|
id integer not null,
|
||||||
|
t_group integer not null
|
||||||
|
);
|
||||||
|
|
||||||
|
alter table groups add constraint pk_groups primary key (gr_id);
|
||||||
|
alter table test add constraint pk_test primary key (id, t_group);
|
||||||
|
alter table test add constraint fk_test foreign key (t_group) references groups (gr_id);
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
alter procedure group_copy (
|
||||||
|
source integer,
|
||||||
|
destination integer)
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
insert into test( id, t_group )
|
||||||
|
select a.id, :destination
|
||||||
|
from test a
|
||||||
|
where a.t_group = :source
|
||||||
|
and not exists (
|
||||||
|
select * from test b
|
||||||
|
where b.id = a.id
|
||||||
|
and :destination = b.t_group
|
||||||
|
);
|
||||||
|
end
|
||||||
|
^
|
||||||
|
|
||||||
|
alter procedure insert_values (
|
||||||
|
cont integer,
|
||||||
|
d_group integer)
|
||||||
|
as
|
||||||
|
declare anz integer;
|
||||||
|
begin
|
||||||
|
anz = 0;
|
||||||
|
|
||||||
|
while ( anz < cont ) do
|
||||||
|
begin
|
||||||
|
if ( not exists (
|
||||||
|
select id
|
||||||
|
from test where id = :anz
|
||||||
|
and t_group = :d_group
|
||||||
|
)
|
||||||
|
) then
|
||||||
|
insert into test( id, t_group ) values( :anz, :d_group );
|
||||||
|
|
||||||
|
anz = anz +1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
|
||||||
|
insert into groups values ( 1 , 'Group1' );
|
||||||
|
insert into groups values ( 2 , 'Group2' );
|
||||||
|
commit;
|
||||||
|
execute procedure insert_values( 3000 , 1);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
delete from test where t_group = 2;
|
||||||
|
execute procedure group_copy( 1 , 2 );
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
select count(*) from test;
|
||||||
|
select * from groups;
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
COUNT 6000
|
||||||
|
GR_ID 1
|
||||||
|
GR_NAME Group1
|
||||||
|
GR_ID 2
|
||||||
|
GR_NAME Group2
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
419
tests/bugs/core_0304_test.py
Normal file
419
tests/bugs/core_0304_test.py
Normal file
@ -0,0 +1,419 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0304
|
||||||
|
# title: ANY user can drop procedures, generators, exceptions.
|
||||||
|
# decription:
|
||||||
|
# fb30Cs, build 3.0.4.32924: OK, 4.406s.
|
||||||
|
# FB30SS, build 3.0.4.32939: OK, 1.563s.
|
||||||
|
#
|
||||||
|
# 24.01.2019. Added separate code for running on FB 4.0+.
|
||||||
|
# UDF usage is deprecated in FB 4+, see: ".../doc/README.incompatibilities.3to4.txt".
|
||||||
|
# Functions div, frac, dow, sdow, getExactTimestampUTC and isLeapYear got safe replacement
|
||||||
|
# in UDR library "udf_compat", see it in folder: ../plugins/udr/
|
||||||
|
# Checked on:
|
||||||
|
# 4.0.0.1172: OK, 8.140s.
|
||||||
|
# 4.0.0.1340: OK, 4.797s.
|
||||||
|
# 4.0.0.1378: OK, 4.032s.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-304
|
||||||
|
# min_versions: ['3.0']
|
||||||
|
# versions: 3.0, 4.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create or alter user tmp$c0304 password '123';
|
||||||
|
commit;
|
||||||
|
|
||||||
|
DECLARE EXTERNAL FUNCTION strlen CSTRING(32767) RETURNS INTEGER BY VALUE ENTRY_POINT 'IB_UDF_strlen' MODULE_NAME 'ib_udf';
|
||||||
|
|
||||||
|
create domain dm_test int;
|
||||||
|
create collation name_coll for utf8 from unicode case insensitive;
|
||||||
|
create sequence g_test;
|
||||||
|
create exception e_test 'foo';
|
||||||
|
create or alter procedure sp_test as begin end;
|
||||||
|
create table test(id int not null, x int);
|
||||||
|
alter table test add constraint test_pk primary key(id) using index test_pk;
|
||||||
|
create index test_x on test(x);
|
||||||
|
create view v_test as select * from test;
|
||||||
|
create role manager;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create or alter trigger test_bi for test active
|
||||||
|
before insert position 0
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
new.id = coalesce(new.id, gen_id(g_test, 1) );
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
connect '$(DSN)' user 'tmp$c0304' password '123';
|
||||||
|
|
||||||
|
-- All following statements should FAIL if current user is not SYSDBA:
|
||||||
|
|
||||||
|
execute procedure sp_test;
|
||||||
|
|
||||||
|
show sequence g_test;
|
||||||
|
|
||||||
|
alter domain dm_test set default 123;
|
||||||
|
|
||||||
|
alter domain dm_test set not null;
|
||||||
|
|
||||||
|
alter domain dm_test drop not null;
|
||||||
|
|
||||||
|
alter trigger test_bi inactive;
|
||||||
|
|
||||||
|
|
||||||
|
alter table test add z int;
|
||||||
|
|
||||||
|
alter table test drop constraint test_pk;
|
||||||
|
|
||||||
|
drop index test_x;
|
||||||
|
|
||||||
|
drop view v_test;
|
||||||
|
|
||||||
|
drop trigger test_bi;
|
||||||
|
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
drop role manager;
|
||||||
|
|
||||||
|
drop procedure sp_test;
|
||||||
|
|
||||||
|
drop sequence g_test;
|
||||||
|
|
||||||
|
drop exception e_test;
|
||||||
|
|
||||||
|
drop function strlen;
|
||||||
|
|
||||||
|
|
||||||
|
drop collation name_coll;
|
||||||
|
|
||||||
|
rollback;
|
||||||
|
connect '$(DSN)' user 'SYSDBA' password 'masterkey';
|
||||||
|
drop user tmp$c0304;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
no permission for EXECUTE access to PROCEDURE SP_TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
no permission for USAGE access to GENERATOR G_TEST
|
||||||
|
There is no generator G_TEST in this database
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER DOMAIN DM_TEST failed
|
||||||
|
-no permission for ALTER access to DOMAIN DM_TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER DOMAIN DM_TEST failed
|
||||||
|
-no permission for ALTER access to DOMAIN DM_TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER DOMAIN DM_TEST failed
|
||||||
|
-no permission for ALTER access to DOMAIN DM_TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER TRIGGER TEST_BI failed
|
||||||
|
-no permission for ALTER access to TABLE TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER TABLE TEST failed
|
||||||
|
-no permission for ALTER access to TABLE TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER TABLE TEST failed
|
||||||
|
-no permission for ALTER access to TABLE TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP INDEX TEST_X failed
|
||||||
|
-no permission for ALTER access to TABLE TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP TABLE V_TEST failed
|
||||||
|
-no permission for DROP access to VIEW V_TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP TRIGGER TEST_BI failed
|
||||||
|
-no permission for ALTER access to TABLE TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP TABLE TEST failed
|
||||||
|
-no permission for DROP access to TABLE TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP ROLE MANAGER failed
|
||||||
|
-no permission for DROP access to ROLE MANAGER
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP PROCEDURE SP_TEST failed
|
||||||
|
-no permission for DROP access to PROCEDURE SP_TEST
|
||||||
|
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP SEQUENCE G_TEST failed
|
||||||
|
-no permission for DROP access to GENERATOR G_TEST
|
||||||
|
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP EXCEPTION E_TEST failed
|
||||||
|
-no permission for DROP access to EXCEPTION E_TEST
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP FUNCTION STRLEN failed
|
||||||
|
-no permission for DROP access to FUNCTION STRLEN
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP COLLATION NAME_COLL failed
|
||||||
|
-no permission for DROP access to COLLATION NAME_COLL
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0,<4.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
||||||
|
# version: 4.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_2 = []
|
||||||
|
|
||||||
|
init_script_2 = """"""
|
||||||
|
|
||||||
|
db_2 = db_factory(sql_dialect=3, init=init_script_2)
|
||||||
|
|
||||||
|
test_script_2 = """
|
||||||
|
create or alter user tmp$c0304 password '123';
|
||||||
|
commit;
|
||||||
|
|
||||||
|
-- See declaration sample in plugins\\udr\\UdfBackwardCompatibility.sql:
|
||||||
|
|
||||||
|
create function UDR40_frac (
|
||||||
|
val double precision
|
||||||
|
) returns double precision
|
||||||
|
external name 'udf_compat!UC_frac'
|
||||||
|
engine udr;
|
||||||
|
|
||||||
|
|
||||||
|
create domain dm_test int;
|
||||||
|
create collation name_coll for utf8 from unicode case insensitive;
|
||||||
|
create sequence g_test;
|
||||||
|
create exception e_test 'foo';
|
||||||
|
create or alter procedure sp_test as begin end;
|
||||||
|
create table test(id int not null, x int);
|
||||||
|
alter table test add constraint test_pk primary key(id) using index test_pk;
|
||||||
|
create index test_x on test(x);
|
||||||
|
create view v_test as select * from test;
|
||||||
|
create role manager;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create or alter trigger test_bi for test active
|
||||||
|
before insert position 0
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
new.id = coalesce(new.id, gen_id(g_test, 1) );
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
connect '$(DSN)' user 'tmp$c0304' password '123';
|
||||||
|
|
||||||
|
-- All following statements should FAIL if current user is not SYSDBA:
|
||||||
|
|
||||||
|
execute procedure sp_test;
|
||||||
|
|
||||||
|
show sequence g_test;
|
||||||
|
|
||||||
|
alter domain dm_test set default 123;
|
||||||
|
|
||||||
|
alter domain dm_test set not null;
|
||||||
|
|
||||||
|
alter domain dm_test drop not null;
|
||||||
|
|
||||||
|
alter trigger test_bi inactive;
|
||||||
|
|
||||||
|
|
||||||
|
alter table test add z int;
|
||||||
|
|
||||||
|
alter table test drop constraint test_pk;
|
||||||
|
|
||||||
|
drop index test_x;
|
||||||
|
|
||||||
|
drop view v_test;
|
||||||
|
|
||||||
|
drop trigger test_bi;
|
||||||
|
|
||||||
|
drop table test;
|
||||||
|
|
||||||
|
drop role manager;
|
||||||
|
|
||||||
|
drop procedure sp_test;
|
||||||
|
|
||||||
|
drop sequence g_test;
|
||||||
|
|
||||||
|
drop exception e_test;
|
||||||
|
|
||||||
|
drop function UDR40_frac;
|
||||||
|
|
||||||
|
drop collation name_coll;
|
||||||
|
|
||||||
|
rollback;
|
||||||
|
connect '$(DSN)' user 'SYSDBA' password 'masterkey';
|
||||||
|
drop user tmp$c0304;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_2 = isql_act('db_2', test_script_2, substitutions=substitutions_2)
|
||||||
|
|
||||||
|
expected_stderr_2 = """
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
no permission for EXECUTE access to PROCEDURE SP_TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
no permission for USAGE access to GENERATOR G_TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
There is no generator G_TEST in this database
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER DOMAIN DM_TEST failed
|
||||||
|
-no permission for ALTER access to DOMAIN DM_TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER DOMAIN DM_TEST failed
|
||||||
|
-no permission for ALTER access to DOMAIN DM_TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER DOMAIN DM_TEST failed
|
||||||
|
-no permission for ALTER access to DOMAIN DM_TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER TRIGGER TEST_BI failed
|
||||||
|
-no permission for ALTER access to TABLE TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER TABLE TEST failed
|
||||||
|
-no permission for ALTER access to TABLE TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER TABLE TEST failed
|
||||||
|
-no permission for ALTER access to TABLE TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP INDEX TEST_X failed
|
||||||
|
-no permission for ALTER access to TABLE TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP TABLE V_TEST failed
|
||||||
|
-no permission for DROP access to VIEW V_TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP TRIGGER TEST_BI failed
|
||||||
|
-no permission for ALTER access to TABLE TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP TABLE TEST failed
|
||||||
|
-no permission for DROP access to TABLE TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP ROLE MANAGER failed
|
||||||
|
-no permission for DROP access to ROLE MANAGER
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP PROCEDURE SP_TEST failed
|
||||||
|
-no permission for DROP access to PROCEDURE SP_TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP SEQUENCE G_TEST failed
|
||||||
|
-no permission for DROP access to GENERATOR G_TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP EXCEPTION E_TEST failed
|
||||||
|
-no permission for DROP access to EXCEPTION E_TEST
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP FUNCTION UDR40_FRAC failed
|
||||||
|
-no permission for DROP access to FUNCTION UDR40_FRAC
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-DROP COLLATION NAME_COLL failed
|
||||||
|
-no permission for DROP access to COLLATION NAME_COLL
|
||||||
|
-Effective user is TMP$C0304
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=4.0')
|
||||||
|
def test_2(act_2: Action):
|
||||||
|
act_2.expected_stderr = expected_stderr_2
|
||||||
|
act_2.execute()
|
||||||
|
assert act_2.clean_expected_stderr == act_2.clean_stderr
|
||||||
|
|
586
tests/bugs/core_0335_test.py
Normal file
586
tests/bugs/core_0335_test.py
Normal file
@ -0,0 +1,586 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0335
|
||||||
|
# title: Unsuccessful execution caused by system error <...> bad BLR -- invalid stream
|
||||||
|
# decription:
|
||||||
|
# Original ticket title: "Lost connexion with Big request"
|
||||||
|
# Test checks that:
|
||||||
|
# 1) we *can* run query with <N> unions, where <N> is limit specific for 2.5.x vs 3.x
|
||||||
|
# 2) we can *not* run query with <N+1> unions.
|
||||||
|
# Actual value of <N> is 128 for 2.5.x (NOT 255 as errormessage issues!) and 255 for 3.0.
|
||||||
|
#
|
||||||
|
# Checked on WI-V2.5.7.27025, WI-V3.0.1.32598.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-335
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """
|
||||||
|
recreate table test(id int);
|
||||||
|
commit;
|
||||||
|
insert into test select 1 from rdb$types rows 10;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
set count on;
|
||||||
|
|
||||||
|
-- ##########################
|
||||||
|
-- FIRST QUERY: SHOULD PASS.
|
||||||
|
-- ##########################
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 10
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 20
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 30
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 40
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 50
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 60
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 70
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 80
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 90
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --100
|
||||||
|
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --110
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --120
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- last allowed in 2.5.7; add subsequent leads in 2.5.x to Too many Contexts of Relation/Procedure/Views. Maximum allowed is 255
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --130
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --140
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --150
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --160
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --170
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --180
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --190
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --200
|
||||||
|
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --210
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --220
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --230
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --240
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --250
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test ------------------- last allowed in 3.0
|
||||||
|
; /* union select first 5 * from test; */
|
||||||
|
|
||||||
|
|
||||||
|
-- ##########################
|
||||||
|
-- SECOND QUERY: SHOULD FAIL.
|
||||||
|
-- ##########################
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 10
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 20
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 30
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 40
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 50
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 60
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 70
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 80
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- 90
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --100
|
||||||
|
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --110
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --120
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union -- last allowed in 2.5.7; add subsequent leads in 2.5.x to Too many Contexts of Relation/Procedure/Views. Maximum allowed is 255
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --130
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --140
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --150
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --160
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --170
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --180
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --190
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --200
|
||||||
|
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --210
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --220
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --230
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --240
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union --250
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test union
|
||||||
|
select first 5 * from test ------------------- last allowed in 3.0
|
||||||
|
union all select first 5 * from test;
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
ID 1
|
||||||
|
Records affected: 1
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 54001
|
||||||
|
Dynamic SQL Error
|
||||||
|
-Too many Contexts of Relation/Procedure/Views. Maximum allowed is 256
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
147
tests/bugs/core_0337_test.py
Normal file
147
tests/bugs/core_0337_test.py
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0337
|
||||||
|
# title: bug #910430 ISQL and database dialect
|
||||||
|
# decription:
|
||||||
|
# ::: NB :::
|
||||||
|
# ### Name of original test has no any relation with actual task of this test: ###
|
||||||
|
# https://github.com/FirebirdSQL/fbtcs/blob/master/GTCS/tests/CF_ISQL_25.script
|
||||||
|
#
|
||||||
|
# When ISQL disconnects from database (either by dropping it or by trying to connect to
|
||||||
|
# non-existent database) is still remembers its sql dialect, which can lead to some
|
||||||
|
# inappropriate warning messages.
|
||||||
|
#
|
||||||
|
# Issue in original script: bug #910430 ISQL and database dialect
|
||||||
|
# Found in FB tracker as: http://tracker.firebirdsql.org/browse/CORE-337
|
||||||
|
# Fixed in 2.0 Beta 1
|
||||||
|
#
|
||||||
|
# Checked on: 4.0.0.1803 SS; 3.0.6.33265 SS; 2.5.9.27149 SC.
|
||||||
|
#
|
||||||
|
# tracker_id:
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('[ \t]+', ' '), ('CREATE DATABASE.*', 'CREATE DATABASE')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
# test_script_1
|
||||||
|
#---
|
||||||
|
#
|
||||||
|
# import os
|
||||||
|
# import sys
|
||||||
|
# import subprocess
|
||||||
|
#
|
||||||
|
# #--------------------------------------------
|
||||||
|
#
|
||||||
|
# def flush_and_close(file_handle):
|
||||||
|
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||||
|
# # If you're starting with a Python file object f,
|
||||||
|
# # first do f.flush(), and
|
||||||
|
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||||
|
# global os
|
||||||
|
#
|
||||||
|
# file_handle.flush()
|
||||||
|
# if file_handle.mode not in ('r', 'rb'):
|
||||||
|
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||||
|
# os.fsync(file_handle.fileno())
|
||||||
|
# file_handle.close()
|
||||||
|
#
|
||||||
|
# #--------------------------------------------
|
||||||
|
#
|
||||||
|
# def cleanup( f_names_list ):
|
||||||
|
# global os
|
||||||
|
# for i in range(len( f_names_list )):
|
||||||
|
# if os.path.isfile( f_names_list[i]):
|
||||||
|
# os.remove( f_names_list[i] )
|
||||||
|
#
|
||||||
|
# #--------------------------------------------
|
||||||
|
#
|
||||||
|
# test_fdb=os.path.join(context['temp_directory'],'tmp_0337.fdb')
|
||||||
|
#
|
||||||
|
# cleanup( test_fdb, )
|
||||||
|
#
|
||||||
|
# db_conn.close()
|
||||||
|
# sql='''
|
||||||
|
# set echo on;
|
||||||
|
#
|
||||||
|
# show sql dialect;
|
||||||
|
#
|
||||||
|
# set sql dialect 1;
|
||||||
|
#
|
||||||
|
# show sql dialect;
|
||||||
|
#
|
||||||
|
# set sql dialect 3;
|
||||||
|
#
|
||||||
|
# create database 'localhost:%(test_fdb)s' user '%(user_name)s' password '%(user_password)s';
|
||||||
|
#
|
||||||
|
# show sql dialect;
|
||||||
|
#
|
||||||
|
# drop database;
|
||||||
|
#
|
||||||
|
# show database;
|
||||||
|
#
|
||||||
|
# show sql dialect;
|
||||||
|
#
|
||||||
|
# set sql dialect 1;
|
||||||
|
# ''' % dict(globals(), **locals())
|
||||||
|
#
|
||||||
|
# f_sql_chk = open( os.path.join(context['temp_directory'],'tmp_0337_ddl.sql'), 'w', buffering = 0)
|
||||||
|
# f_sql_chk.write(sql)
|
||||||
|
# flush_and_close( f_sql_chk )
|
||||||
|
#
|
||||||
|
# f_sql_log = open( ''.join( (os.path.splitext(f_sql_chk.name)[0], '.log' ) ), 'w', buffering = 0)
|
||||||
|
# subprocess.call( [ context['isql_path'], '-q', '-i', f_sql_chk.name ], stdout = f_sql_log, stderr = subprocess.STDOUT)
|
||||||
|
# flush_and_close( f_sql_log )
|
||||||
|
#
|
||||||
|
# with open(f_sql_log.name,'r') as f:
|
||||||
|
# for line in f:
|
||||||
|
# if line.split():
|
||||||
|
# print( line.upper() )
|
||||||
|
#
|
||||||
|
# cleanup( (test_fdb, f_sql_log.name, f_sql_chk.name) )
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#---
|
||||||
|
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
SHOW SQL DIALECT;
|
||||||
|
CLIENT SQL DIALECT HAS NOT BEEN SET AND NO DATABASE HAS BEEN CONNECTED YET.
|
||||||
|
|
||||||
|
SET SQL DIALECT 1;
|
||||||
|
SHOW SQL DIALECT;
|
||||||
|
CLIENT SQL DIALECT IS SET TO: 1. NO DATABASE HAS BEEN CONNECTED.
|
||||||
|
|
||||||
|
SET SQL DIALECT 3;
|
||||||
|
CREATE DATABASE 'LOCALHOST:C:\\FBTESTING\\QA\\FBT-REPO\\TMP2\\TMP_0337.FDB' USER 'SYSDBA' PASSWORD 'MASTERKEY';
|
||||||
|
|
||||||
|
SHOW SQL DIALECT;
|
||||||
|
CLIENT SQL DIALECT IS SET TO: 3 AND DATABASE SQL DIALECT IS: 3
|
||||||
|
|
||||||
|
DROP DATABASE;
|
||||||
|
|
||||||
|
SHOW DATABASE;
|
||||||
|
COMMAND ERROR: SHOW DATABASE
|
||||||
|
|
||||||
|
SHOW SQL DIALECT;
|
||||||
|
CLIENT SQL DIALECT IS SET TO: 3. NO DATABASE HAS BEEN CONNECTED.
|
||||||
|
|
||||||
|
SET SQL DIALECT 1;
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
@pytest.mark.xfail
|
||||||
|
def test_1(db_1):
|
||||||
|
pytest.fail("Test not IMPLEMENTED")
|
||||||
|
|
||||||
|
|
465
tests/bugs/core_0366_test.py
Normal file
465
tests/bugs/core_0366_test.py
Normal file
@ -0,0 +1,465 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0366
|
||||||
|
# title: Complex view crashes server
|
||||||
|
# decription:
|
||||||
|
# NOTE-1.
|
||||||
|
# Name of original test has no any relation with actual task of this test: ###
|
||||||
|
# https://github.com/FirebirdSQL/fbtcs/blob/master/GTCS/tests/CF_ISQL_26.script
|
||||||
|
#
|
||||||
|
# Issue in original script: bug #583690 Complex view crashes server
|
||||||
|
# Found in FB tracker as: http://tracker.firebirdsql.org/browse/CORE-366
|
||||||
|
# Fixed on 2.0 Beta 1
|
||||||
|
#
|
||||||
|
# NOTE-2.
|
||||||
|
# We expect that compilation of this test script finished OK, without any errors/warnings.
|
||||||
|
# 2.5 issues "too many contexts / max allowed 255'; because of this, min_version=3.0
|
||||||
|
#
|
||||||
|
# Checked on: 4.0.0.1803; 3.0.6.33265
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0366
|
||||||
|
# min_versions: ['3.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
CREATE TABLE DRZAVA(
|
||||||
|
POZIVNIBROJDRZAVE VARCHAR(4) NOT NULL,
|
||||||
|
NAZIVDRZAVE VARCHAR(20),
|
||||||
|
GRUPA INTEGER NOT NULL,
|
||||||
|
PRIMARY KEY(POZIVNIBROJDRZAVE)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE LOG (
|
||||||
|
BROJ VARCHAR(25) NOT NULL,
|
||||||
|
POCETAK TIMESTAMP NOT NULL,
|
||||||
|
TRAJANJE INTEGER NOT NULL,
|
||||||
|
LOKAL INTEGER,
|
||||||
|
LINIJA INTEGER,
|
||||||
|
CENA NUMERIC(8,2) NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE LOKAL(
|
||||||
|
BROJLOKALA INTEGER NOT NULL,
|
||||||
|
NAZIVLOKALA VARCHAR(25) NOT NULL,
|
||||||
|
PRIMARY KEY(BROJLOKALA)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE MESNI(
|
||||||
|
PTT CHAR(5) NOT NULL,
|
||||||
|
LOKALNIPREFIX VARCHAR(5) NOT NULL,
|
||||||
|
PRIMARY KEY (PTT,LOKALNIPREFIX)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE MREZA(
|
||||||
|
BROJMREZE VARCHAR(4) NOT NULL,
|
||||||
|
POZIVNIBROJ VARCHAR(4) NOT NULL,
|
||||||
|
ZONA INTEGER NOT NULL,
|
||||||
|
PRIMARY KEY (BROJMREZE,POZIVNIBROJ)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE VrstaRT(
|
||||||
|
SifraVRT char(7) NOT NULL,
|
||||||
|
NazivVRT varchar(30) NOT NULL,
|
||||||
|
JM varchar(6),
|
||||||
|
PRIMARY KEY (SifraVRT)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE Poslovnica(
|
||||||
|
SifraPoslovnice char(2) NOT NULL,
|
||||||
|
NazivPoslovnice varchar(18) NOT NULL,
|
||||||
|
PRIMARY KEY(SifraPoslovnice)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE RezijskiTrosak(
|
||||||
|
RedniBroj integer NOT NULL,
|
||||||
|
DatumTroska timestamp NOT NULL,
|
||||||
|
SifraPoslovnice char(2) NOT NULL
|
||||||
|
REFERENCES Poslovnica (SifraPoslovnice) ON UPDATE CASCADE,
|
||||||
|
SifraVRT char(7) NOT NULL
|
||||||
|
REFERENCES VrstaRT(SifraVRT) ON UPDATE CASCADE,
|
||||||
|
Kolicina decimal(8,2),
|
||||||
|
Iznos decimal(8,2) NOT NULL,
|
||||||
|
PRIMARY KEY (RedniBroj)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE GENERATOR GEN_RT_ID;
|
||||||
|
SET GENERATOR GEN_RT_ID TO 0;
|
||||||
|
|
||||||
|
CREATE TABLE VrstaMT(
|
||||||
|
SifraVMT char(7) NOT NULL,
|
||||||
|
NazivVMT varchar(30) NOT NULL,
|
||||||
|
DefaultJM varchar(6),
|
||||||
|
PRIMARY KEY(SifraVMT)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE Roba(
|
||||||
|
SifraRobe char(6) NOT NULL,
|
||||||
|
VrstaRobe char(7) NOT NULL
|
||||||
|
REFERENCES VrstaMT (SifraVMT) ON UPDATE CASCADE,
|
||||||
|
NazivRobe varchar(30) NOT NULL,
|
||||||
|
JM varchar(6) NOT NULL,
|
||||||
|
BarCode varchar(50),
|
||||||
|
Pakovanje integer,
|
||||||
|
Napomena varchar(100),
|
||||||
|
PRIMARY KEY(SifraRobe)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE Mesto(
|
||||||
|
PTT char(5) NOT NULL,
|
||||||
|
NazivMesta varchar(40) NOT NULL,
|
||||||
|
PozivniBroj char(4),
|
||||||
|
PRIMARY KEY(PTT)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE Komitent(
|
||||||
|
SifraKomitenta integer NOT NULL,
|
||||||
|
Naziv varchar(25) NOT NULL ,
|
||||||
|
PTT char(5) NOT NULL
|
||||||
|
REFERENCES Mesto(PTT) ON UPDATE CASCADE,
|
||||||
|
Napomena varchar(100),
|
||||||
|
Owner char(8),
|
||||||
|
PRIMARY KEY(SifraKomitenta)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE GENERATOR GEN_Komitent_ID;
|
||||||
|
SET GENERATOR GEN_Komitent_ID TO 0;
|
||||||
|
|
||||||
|
CREATE TABLE VrstaDetalja(
|
||||||
|
SifraVD integer NOT NULL,
|
||||||
|
OpisVD varchar(15),
|
||||||
|
Telefon char(1),
|
||||||
|
CHECK (telefon is null or telefon = 'D' or telefon ='Z'),
|
||||||
|
PRIMARY KEY(SifraVD)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE GENERATOR GEN_VrstaDetalja_ID;
|
||||||
|
SET GENERATOR GEN_VrstaDetalja_ID TO 0;
|
||||||
|
|
||||||
|
CREATE TABLE KomitentDetaljno (
|
||||||
|
SifraKD integer NOT NULL,
|
||||||
|
SifraKomitenta integer NOT NULL
|
||||||
|
REFERENCES Komitent (SifraKomitenta) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||||
|
SifraVD integer NOT NULL
|
||||||
|
REFERENCES VrstaDetalja (SifraVD) ON UPDATE CASCADE,
|
||||||
|
Podatak varchar(40) NOT NULL,
|
||||||
|
CistBroj varchar(25),
|
||||||
|
PRIMARY KEY(SifraKD)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE GENERATOR GEN_KOMITENTDETALJNO_ID;
|
||||||
|
SET GENERATOR GEN_KOMITENTDETALJNO_ID TO 0;
|
||||||
|
|
||||||
|
CREATE TABLE Prijem(
|
||||||
|
BRDOK integer NOT NULL,
|
||||||
|
DatumUlaza timestamp NOT NULL,
|
||||||
|
SifraKomitenta integer
|
||||||
|
REFERENCES Komitent(SifraKomitenta) ON UPDATE CASCADE,
|
||||||
|
PRIMARY KEY(BRDOK)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE GENERATOR GEN_PRIJ_ID;
|
||||||
|
SET GENERATOR GEN_PRIJ_ID TO 0;
|
||||||
|
|
||||||
|
CREATE TABLE Prijemst(
|
||||||
|
BRDOK integer NOT NULL
|
||||||
|
REFERENCES Prijem(BRDOK) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||||
|
SifraRobe char(6) NOT NULL
|
||||||
|
REFERENCES ROBA(SifraRobe) ON UPDATE CASCADE,
|
||||||
|
Kolicina decimal(8,2) NOT NULL,
|
||||||
|
Cena decimal(8,2) NOT NULL,
|
||||||
|
PRIMARY KEY (BRDOK,SifraRobe)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE Alokacija(
|
||||||
|
Brdok integer NOT NULL,
|
||||||
|
Datum timestamp NOT NULL,
|
||||||
|
SifraPoslovnice char(2) NOT NULL
|
||||||
|
REFERENCES Poslovnica (SifraPoslovnice) ON UPDATE CASCADE,
|
||||||
|
PRIMARY KEY (Brdok)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE GENERATOR GEN_ALOK_ID;
|
||||||
|
SET GENERATOR GEN_ALOK_ID TO 1;
|
||||||
|
|
||||||
|
CREATE TABLE Alokacijast(
|
||||||
|
Brdok integer NOT NULL
|
||||||
|
REFERENCES Alokacija(BRDOK) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||||
|
SifraRobe char(6) NOT NULL
|
||||||
|
REFERENCES ROBA(SifraRobe) ON UPDATE CASCADE,
|
||||||
|
Kolicina decimal(8,2) NOT NULL,
|
||||||
|
Cena decimal(8,2) NOT NULL,
|
||||||
|
PRIMARY KEY (Brdok,SifraRobe)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE VrstaGoriva(
|
||||||
|
SifraVrsteGoriva Integer NOT NULL,
|
||||||
|
NazivVrsteGoriva varchar(10) NOT NULL,
|
||||||
|
PRIMARY KEY(SifraVrsteGoriva)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
CREATE TABLE VrstaVozila(
|
||||||
|
SifraVrste char(2) NOT NULL,
|
||||||
|
NazivVrste varchar(18) NOT NULL,
|
||||||
|
PRIMARY KEY(SifraVrste)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE Vozilo(
|
||||||
|
SifraVozila char(12) NOT NULL,
|
||||||
|
SifraVrste char(2) NOT NULL
|
||||||
|
REFERENCES VrstaVozila (SifraVrste) ON UPDATE CASCADE,
|
||||||
|
RegBroj char(10),
|
||||||
|
Marka char(10),
|
||||||
|
Tip char(20),
|
||||||
|
BrojSasije char(25),
|
||||||
|
BrojMotora char(25),
|
||||||
|
PrvaRegistracija timestamp,
|
||||||
|
SnagaMotora decimal(10,2),
|
||||||
|
Zapremina integer,
|
||||||
|
Nosivost integer,
|
||||||
|
MestaZaSedenje char(4),
|
||||||
|
Karoserija char(25),
|
||||||
|
Boja char(20),
|
||||||
|
BrojOsovina char(1),
|
||||||
|
RokPPAparata timestamp,
|
||||||
|
PRIMARY KEY(SifraVozila)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE Vozac(
|
||||||
|
SifraVozaca integer NOT NULL,
|
||||||
|
Ime char(25) NOT NULL,
|
||||||
|
Kategorije char(5) NOT NULL,
|
||||||
|
DatumVazenjaDozvole Timestamp,
|
||||||
|
PRIMARY KEY(SifraVozaca)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE SipanjeGoriva(
|
||||||
|
SifraSG integer NOT NULL,
|
||||||
|
Datum Timestamp NOT NULL,
|
||||||
|
SifraVozila char(12) NOT NULL
|
||||||
|
REFERENCES Vozilo(SifraVozila) ON UPDATE CASCADE,
|
||||||
|
SifraVozaca integer NOT NULL
|
||||||
|
REFERENCES Vozac(SifraVozaca) ON UPDATE CASCADE,
|
||||||
|
SifraVrsteGoriva integer NOT NULL
|
||||||
|
REFERENCES VrstaGoriva (SifraVrsteGoriva) ON UPDATE CASCADE,
|
||||||
|
SifraPoslovnice char(2) NOT NULL
|
||||||
|
REFERENCES Poslovnica (SifraPoslovnice) ON UPDATE CASCADE,
|
||||||
|
KMsat decimal(9,1),
|
||||||
|
Kolicina decimal(10, 2) NOT NULL,
|
||||||
|
Cena decimal(8,2) NOT NULL,
|
||||||
|
PunDoCepa char(1),
|
||||||
|
CHECK (PunDoCepa = 'N' or PunDoCepa = 'D'),
|
||||||
|
PRIMARY KEY (SifraSG)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE GENERATOR GEN_GORIVO_ID;
|
||||||
|
SET GENERATOR GEN_GORIVO_ID TO 1;
|
||||||
|
|
||||||
|
CREATE TABLE Popravka(
|
||||||
|
Datum Timestamp NOT NULL,
|
||||||
|
SifraVozila char(12) NOT NULL
|
||||||
|
REFERENCES Vozilo(SifraVozila) ON UPDATE CASCADE,
|
||||||
|
SifraVozaca integer NOT NULL
|
||||||
|
REFERENCES Vozac(SifraVozaca) ON UPDATE CASCADE,
|
||||||
|
SifraPoslovnice char(2) NOT NULL
|
||||||
|
REFERENCES Poslovnica (SifraPoslovnice) ON UPDATE CASCADE,
|
||||||
|
Iznos decimal(12,2) NOT NULL,
|
||||||
|
Opis varchar(200),
|
||||||
|
PRIMARY KEY(Datum,SifraVozila)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE Registracija(
|
||||||
|
Datum Timestamp NOT NULL,
|
||||||
|
SifraVozila char(12) NOT NULL
|
||||||
|
REFERENCES Vozilo(SifraVozila) ON UPDATE CASCADE,
|
||||||
|
CenaTehnickog decimal(12,2),
|
||||||
|
CenaOsiguranja decimal(12,2),
|
||||||
|
OstaliTroskovi decimal(12,2),
|
||||||
|
SifraPoslovnice char(2) NOT NULL
|
||||||
|
REFERENCES Poslovnica (SifraPoslovnice) ON UPDATE CASCADE,
|
||||||
|
PRIMARY KEY(Datum,SifraVozila)
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE DUMMY(
|
||||||
|
foobar integer NOT NULL primary key,
|
||||||
|
check (foobar = 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
INSERT INTO dummy VALUES(1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CREATE VIEW APROMET(DATUM, SO, VRSTA,IZNOS) AS
|
||||||
|
select
|
||||||
|
rt.datumtroska,
|
||||||
|
SIFRAPOSLOVNICE,
|
||||||
|
cast(vrt.nazivvrt as varchar(30)),
|
||||||
|
cast(rt.iznos as numeric(18, 2))
|
||||||
|
from rezijskitrosak rt
|
||||||
|
left join VRSTART vrt on rt.sifravrt = vrt.sifravrt
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
AL.DATUM,
|
||||||
|
SIFRAPOSLOVNICE,
|
||||||
|
cast('KancMat'as varchar(30)),
|
||||||
|
cast(sum(alst.kolicina * alst.cena) as numeric(18, 2))
|
||||||
|
FROM ALOKACIJAST ALST
|
||||||
|
LEFT JOIN ALOKACIJA AL ON ALST.brdok=AL.brdok
|
||||||
|
LEFT JOIN ROBA R ON ALST.sifrarobe = R.sifrarobe
|
||||||
|
WHERE R.vrstarobe = 'KM'
|
||||||
|
GROUP BY AL.DATUM, SIFRAPOSLOVNICE
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
AL.DATUM,
|
||||||
|
SIFRAPOSLOVNICE,
|
||||||
|
cast ('Hemikalije' as varchar(30)),
|
||||||
|
cast(sum(alst.kolicina * alst.cena) as numeric(18, 2))
|
||||||
|
FROM ALOKACIJAST ALST
|
||||||
|
LEFT JOIN ALOKACIJA AL ON ALST.brdok=AL.brdok
|
||||||
|
LEFT JOIN ROBA R ON ALST.sifrarobe = R.sifrarobe
|
||||||
|
WHERE R.vrstarobe = 'HE'
|
||||||
|
GROUP BY AL.DATUM, SIFRAPOSLOVNICE
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
AL.DATUM,
|
||||||
|
SIFRAPOSLOVNICE,
|
||||||
|
cast('Prehrana' as varchar(30)),
|
||||||
|
cast(sum(alst.kolicina * alst.cena) as numeric(18, 2))
|
||||||
|
FROM ALOKACIJAST ALST
|
||||||
|
LEFT JOIN ALOKACIJA AL ON ALST.brdok=AL.brdok
|
||||||
|
LEFT JOIN ROBA R ON ALST.sifrarobe = R.sifrarobe
|
||||||
|
WHERE R.vrstarobe = 'HR'
|
||||||
|
GROUP BY AL.DATUM, SIFRAPOSLOVNICE
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
pp.datum,
|
||||||
|
SIFRAPOSLOVNICE,
|
||||||
|
cast('Popravke' as varchar(30)),
|
||||||
|
cast(sum(iznos) as numeric(18,2))
|
||||||
|
FROM popravka pp
|
||||||
|
GROUP BY pp.DATUM, SIFRAPOSLOVNICE
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
rg.datum,
|
||||||
|
SIFRAPOSLOVNICE,
|
||||||
|
cast('Registracije' as varchar(30)),
|
||||||
|
cast(sum(cenatehnickog + cenaosiguranja+ostalitroskovi) as numeric(18,2))
|
||||||
|
FROM registracija rg
|
||||||
|
GROUP BY rg.DATUM, SIFRAPOSLOVNICE
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
sg.datum,
|
||||||
|
SIFRAPOSLOVNICE,
|
||||||
|
cast('Gorivo' as varchar(30)),
|
||||||
|
cast(sum(kolicina * cena) as numeric(18,2))
|
||||||
|
FROM sipanjegoriva sg
|
||||||
|
GROUP BY
|
||||||
|
sg.DATUM, SIFRAPOSLOVNICE
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE VIEW VV(VRSTA) AS
|
||||||
|
select distinct vrsta from apromet a;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
|
||||||
|
SELECT vv.VRSTA,
|
||||||
|
(select sum(ap.iznos)
|
||||||
|
from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=1),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=2),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=3),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=4),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=5),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=6),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=7),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=8),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=9),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=10),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=11),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta
|
||||||
|
and
|
||||||
|
extract(month from ap.datum)=12),
|
||||||
|
(select
|
||||||
|
sum(ap.iznos) from apromet ap where ap.vrsta
|
||||||
|
=
|
||||||
|
vv.vrsta)
|
||||||
|
FROM vv;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.execute()
|
||||||
|
|
110
tests/bugs/core_0389_test.py
Normal file
110
tests/bugs/core_0389_test.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0389
|
||||||
|
# title: NULLS FIRST does not work with unions
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-389
|
||||||
|
# min_versions: ['2.0.7']
|
||||||
|
# versions: 2.0.7
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.0.7
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('=.*', '')]
|
||||||
|
|
||||||
|
init_script_1 = """
|
||||||
|
create table t(x int);
|
||||||
|
insert into t values(2222);
|
||||||
|
insert into t values(222 );
|
||||||
|
insert into t values(22);
|
||||||
|
insert into t values(2);
|
||||||
|
insert into t values(null);
|
||||||
|
insert into t values(null);
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
select distinct x
|
||||||
|
from t
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select distinct x
|
||||||
|
from t
|
||||||
|
|
||||||
|
order by 1 nulls first
|
||||||
|
;
|
||||||
|
--------------------------
|
||||||
|
select distinct x
|
||||||
|
from t
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select distinct x
|
||||||
|
from t
|
||||||
|
|
||||||
|
order by 1 desc nulls first
|
||||||
|
;
|
||||||
|
--------------------------
|
||||||
|
select x
|
||||||
|
from t
|
||||||
|
|
||||||
|
union
|
||||||
|
|
||||||
|
select x
|
||||||
|
from t
|
||||||
|
|
||||||
|
order by 1 nulls first
|
||||||
|
;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
X
|
||||||
|
============
|
||||||
|
<null>
|
||||||
|
<null>
|
||||||
|
2
|
||||||
|
2
|
||||||
|
22
|
||||||
|
22
|
||||||
|
222
|
||||||
|
222
|
||||||
|
2222
|
||||||
|
2222
|
||||||
|
|
||||||
|
|
||||||
|
X
|
||||||
|
============
|
||||||
|
<null>
|
||||||
|
<null>
|
||||||
|
2222
|
||||||
|
2222
|
||||||
|
222
|
||||||
|
222
|
||||||
|
22
|
||||||
|
22
|
||||||
|
2
|
||||||
|
2
|
||||||
|
|
||||||
|
X
|
||||||
|
============
|
||||||
|
<null>
|
||||||
|
2
|
||||||
|
22
|
||||||
|
222
|
||||||
|
2222
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.0.7')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
96
tests/bugs/core_0405_test.py
Normal file
96
tests/bugs/core_0405_test.py
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0405
|
||||||
|
# title: Garbage vs indices/constraints
|
||||||
|
# decription:
|
||||||
|
# Confirmed bug on 3.0.4.32924, got:
|
||||||
|
# DatabaseError:
|
||||||
|
# Error while commiting transaction:
|
||||||
|
# - SQLCODE: -803
|
||||||
|
# - attempt to store duplicate value (visible to active transactions) in unique index "TEST_X"
|
||||||
|
# -803
|
||||||
|
# 335544349
|
||||||
|
# ----------------------------------------------------
|
||||||
|
# :: NB ::
|
||||||
|
# No error on Firebird 4.0 (any: SS,SC, CS).
|
||||||
|
# Works OK on: 4.0.0.838
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0405
|
||||||
|
# min_versions: ['3.0.4']
|
||||||
|
# versions: 3.0.4
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0.4
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
# test_script_1
|
||||||
|
#---
|
||||||
|
#
|
||||||
|
# import os
|
||||||
|
# import sys
|
||||||
|
# import fdb
|
||||||
|
#
|
||||||
|
# os.environ["ISC_USER"] = user_name
|
||||||
|
# os.environ["ISC_PASSWORD"] = user_password
|
||||||
|
#
|
||||||
|
# db_conn.close()
|
||||||
|
#
|
||||||
|
# con=fdb.connect( dsn=dsn, no_gc=1 )
|
||||||
|
# #print( con.firebird_version )
|
||||||
|
#
|
||||||
|
# con.execute_immediate('recreate table test(x int)')
|
||||||
|
# con.commit()
|
||||||
|
# cur=con.cursor()
|
||||||
|
#
|
||||||
|
# stm='insert into test( x ) values( ? )'
|
||||||
|
# val = [ (2,), (3,), (3,), (2,) ]
|
||||||
|
# cur.executemany( stm, val )
|
||||||
|
#
|
||||||
|
# cur.execute('select x from test order by x')
|
||||||
|
# for r in cur:
|
||||||
|
# print(r[0])
|
||||||
|
#
|
||||||
|
# cur.execute('delete from test')
|
||||||
|
#
|
||||||
|
# cur.execute('select count(*) from test')
|
||||||
|
# for r in cur:
|
||||||
|
# print(r[0])
|
||||||
|
#
|
||||||
|
# con.execute_immediate('create unique index test_x on test(x)')
|
||||||
|
# con.commit()
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# cur.execute("select rdb$index_name from rdb$indices where rdb$relation_name='TEST'")
|
||||||
|
# for r in cur:
|
||||||
|
# print( r[0].rstrip() )
|
||||||
|
#
|
||||||
|
# con.close()
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#---
|
||||||
|
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
2
|
||||||
|
2
|
||||||
|
3
|
||||||
|
3
|
||||||
|
0
|
||||||
|
TEST_X
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0.4')
|
||||||
|
@pytest.mark.xfail
|
||||||
|
def test_1(db_1):
|
||||||
|
pytest.fail("Test not IMPLEMENTED")
|
||||||
|
|
||||||
|
|
541
tests/bugs/core_0461_test.py
Normal file
541
tests/bugs/core_0461_test.py
Normal file
@ -0,0 +1,541 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0461
|
||||||
|
# title: JOIN including a complex view kills the server
|
||||||
|
# decription:
|
||||||
|
# NB: all versions of 2.1 and 2.5 fail on 2nd query (issue 2002-jul-12) with message about
|
||||||
|
# "too many contexts, max = 256" so this test checks only FB 3.0 and above.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0461
|
||||||
|
# min_versions: ['3.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set bail on;
|
||||||
|
|
||||||
|
create domain d_global_id as varchar(15) not null ;
|
||||||
|
create domain d_long_desc as varchar(200);
|
||||||
|
create domain d_group as integer default 0 check ((value is not null));
|
||||||
|
|
||||||
|
create domain d_global_ref as varchar(15);
|
||||||
|
create domain d_icon as smallint check (((value is null) or (value between 0 and 8)));
|
||||||
|
|
||||||
|
recreate table knowledgestreams (
|
||||||
|
stream_id d_global_id not null,
|
||||||
|
name d_long_desc,
|
||||||
|
content_groups d_group,
|
||||||
|
constraint pk_knowledgestreams primary key (stream_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
recreate table mainmenu (
|
||||||
|
menu_id d_global_id not null,
|
||||||
|
parent_id d_global_ref,
|
||||||
|
description d_long_desc,
|
||||||
|
content_group d_group not null,
|
||||||
|
icon d_icon,
|
||||||
|
constraint pk_mainmenu primary key (menu_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
alter table mainmenu add constraint fk_mainmenu foreign key (parent_id)
|
||||||
|
references mainmenu(menu_id) on delete cascade on update cascade;
|
||||||
|
|
||||||
|
recreate table menu_groups (
|
||||||
|
menu_id d_global_id not null,
|
||||||
|
content_id d_global_id not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create index menu_groups_idx1 on menu_groups (menu_id);
|
||||||
|
create index menu_groups_idx2 on menu_groups (content_id);
|
||||||
|
|
||||||
|
recreate table streammenu (
|
||||||
|
stream_id d_global_id not null,
|
||||||
|
parent d_global_id not null,
|
||||||
|
constraint pk_streammenu primary key (parent, stream_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
alter table streammenu add constraint fk_streammenu_parent foreign key
|
||||||
|
(parent) references mainmenu(menu_id) on delete cascade;
|
||||||
|
|
||||||
|
alter table streammenu add constraint fk_streammenu_stream_id foreign
|
||||||
|
key (stream_id) references knowledgestreams(stream_id) on delete
|
||||||
|
cascade;
|
||||||
|
|
||||||
|
create view fullmenu (
|
||||||
|
code,
|
||||||
|
parent,
|
||||||
|
description,
|
||||||
|
link,
|
||||||
|
content_group
|
||||||
|
) as
|
||||||
|
select menu_id,parent_id,description,cast(null as
|
||||||
|
varchar(100)),content_group from mainmenu
|
||||||
|
union all
|
||||||
|
select m.stream_id, m.parent, s.name
|
||||||
|
,cast('/servlets/uk.co.wmeng.intelus.knowledgestream?action=display&id='
|
||||||
|
|| s.stream_id as varchar(100)),content_groups from streammenu m join
|
||||||
|
knowledgestreams s on s.stream_id = m.stream_id
|
||||||
|
;
|
||||||
|
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
create table drzava
|
||||||
|
(
|
||||||
|
pozivnibrojdrzave varchar(4) not null,
|
||||||
|
nazivdrzave varchar(20),
|
||||||
|
grupa integer not null,
|
||||||
|
primary key (pozivnibrojdrzave)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table log
|
||||||
|
(
|
||||||
|
broj varchar(25) not null,
|
||||||
|
pocetak timestamp not null,
|
||||||
|
trajanje integer not null,
|
||||||
|
lokal integer,
|
||||||
|
linija integer,
|
||||||
|
cena numeric(8,2) not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table lokal
|
||||||
|
(
|
||||||
|
brojlokala integer not null,
|
||||||
|
nazivlokala varchar(25) not null,
|
||||||
|
primary key (brojlokala)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table mesni
|
||||||
|
(
|
||||||
|
ptt char(5) not null,
|
||||||
|
lokalniprefix varchar(5) not null,
|
||||||
|
primary key (ptt, lokalniprefix)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table mreza
|
||||||
|
(
|
||||||
|
brojmreze varchar(4) not null,
|
||||||
|
pozivnibroj varchar(4) not null,
|
||||||
|
zona integer not null,
|
||||||
|
primary key (brojmreze, pozivnibroj)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table vrstart
|
||||||
|
(
|
||||||
|
sifravrt char(7) not null,
|
||||||
|
nazivvrt varchar(30) not null,
|
||||||
|
jm varchar(6),
|
||||||
|
primary key (sifravrt)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table poslovnica
|
||||||
|
(
|
||||||
|
sifraposlovnice char(2) not null,
|
||||||
|
nazivposlovnice varchar(18) not null,
|
||||||
|
primary key (sifraposlovnice)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table rezijskitrosak
|
||||||
|
(
|
||||||
|
rednibroj integer not null,
|
||||||
|
datumtroska timestamp not null,
|
||||||
|
sifraposlovnice char(2) not null references
|
||||||
|
poslovnica (sifraposlovnice) on update cascade,
|
||||||
|
sifravrt char(7) not null references vrstart
|
||||||
|
(sifravrt) on update cascade,
|
||||||
|
kolicina decimal(8,2),
|
||||||
|
iznos decimal(8,2) not null,
|
||||||
|
primary key (rednibroj)
|
||||||
|
);
|
||||||
|
|
||||||
|
create generator gen_rt_id;
|
||||||
|
set generator gen_rt_id to 0;
|
||||||
|
|
||||||
|
create table vrstamt
|
||||||
|
(
|
||||||
|
sifravmt char(7) not null,
|
||||||
|
nazivvmt varchar(30) not null,
|
||||||
|
defaultjm varchar(6),
|
||||||
|
primary key (sifravmt)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table roba
|
||||||
|
(
|
||||||
|
sifrarobe char(6) not null,
|
||||||
|
vrstarobe char(7) not null references vrstamt
|
||||||
|
(sifravmt) on update cascade,
|
||||||
|
nazivrobe varchar(30) not null,
|
||||||
|
jm varchar(6) not null,
|
||||||
|
barcode varchar(50),
|
||||||
|
pakovanje integer,
|
||||||
|
napomena varchar(100),
|
||||||
|
primary key (sifrarobe)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table mesto
|
||||||
|
(
|
||||||
|
ptt char(5) not null,
|
||||||
|
nazivmesta varchar(40) not null,
|
||||||
|
pozivnibroj char(4),
|
||||||
|
primary key (ptt)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table komitent
|
||||||
|
(
|
||||||
|
sifrakomitenta integer not null,
|
||||||
|
naziv varchar(25) not null ,
|
||||||
|
ptt char(5) not null references mesto
|
||||||
|
(ptt) on update cascade,
|
||||||
|
napomena varchar(100),
|
||||||
|
owner char(8),
|
||||||
|
primary key (sifrakomitenta)
|
||||||
|
);
|
||||||
|
|
||||||
|
create generator gen_komitent_id;
|
||||||
|
set generator gen_komitent_id to 0;
|
||||||
|
|
||||||
|
create table vrstadetalja
|
||||||
|
(
|
||||||
|
sifravd integer not null,
|
||||||
|
opisvd varchar(15),
|
||||||
|
telefon char(1),
|
||||||
|
check (telefon is null or telefon = 'd' or telefon = 'z'),
|
||||||
|
primary key(sifravd)
|
||||||
|
);
|
||||||
|
|
||||||
|
create generator gen_vrstadetalja_id;
|
||||||
|
set generator gen_vrstadetalja_id to 0;
|
||||||
|
|
||||||
|
create table komitentdetaljno
|
||||||
|
(
|
||||||
|
sifrakd integer not null,
|
||||||
|
sifrakomitenta integer not null references komitent
|
||||||
|
(sifrakomitenta) on update cascade on delete
|
||||||
|
cascade,
|
||||||
|
sifravd integer not null references
|
||||||
|
vrstadetalja (sifravd) on update cascade,
|
||||||
|
podatak varchar(40) not null,
|
||||||
|
cistbroj varchar(25),
|
||||||
|
primary key(sifrakd)
|
||||||
|
);
|
||||||
|
|
||||||
|
create generator gen_komitentdetaljno_id;
|
||||||
|
set generator gen_komitentdetaljno_id to 0;
|
||||||
|
|
||||||
|
create table prijem
|
||||||
|
(
|
||||||
|
brdok integer not null,
|
||||||
|
datumulaza timestamp not null,
|
||||||
|
sifrakomitenta integer references komitent
|
||||||
|
(sifrakomitenta) on update cascade,
|
||||||
|
primary key (brdok)
|
||||||
|
);
|
||||||
|
|
||||||
|
create generator gen_prij_id;
|
||||||
|
set generator gen_prij_id to 0;
|
||||||
|
|
||||||
|
create table prijemst
|
||||||
|
(
|
||||||
|
brdok integer not null references prijem
|
||||||
|
(brdok) on update cascade on delete cascade,
|
||||||
|
sifrarobe char(6) not null references roba
|
||||||
|
(sifrarobe) on update cascade,
|
||||||
|
kolicina decimal(8,2) not null,
|
||||||
|
cena decimal(8,2) not null,
|
||||||
|
primary key (brdok, sifrarobe)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table alokacija
|
||||||
|
(
|
||||||
|
brdok integer not null,
|
||||||
|
datum timestamp not null,
|
||||||
|
sifraposlovnice char(2) not null references poslovnica
|
||||||
|
(sifraposlovnice) on update cascade,
|
||||||
|
primary key (brdok)
|
||||||
|
);
|
||||||
|
|
||||||
|
create generator gen_alok_id;
|
||||||
|
set generator gen_alok_id to 1;
|
||||||
|
|
||||||
|
create table alokacijast
|
||||||
|
(
|
||||||
|
brdok integer not null references alokacija
|
||||||
|
(brdok) on update cascade on delete cascade,
|
||||||
|
sifrarobe char(6) not null references roba
|
||||||
|
(sifrarobe) on update cascade,
|
||||||
|
kolicina decimal(8,2) not null,
|
||||||
|
cena decimal(8,2) not null,
|
||||||
|
primary key (brdok, sifrarobe)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table vrstagoriva
|
||||||
|
(
|
||||||
|
sifravrstegoriva integer not null,
|
||||||
|
nazivvrstegoriva varchar(10) not null,
|
||||||
|
primary key (sifravrstegoriva)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
create table vrstavozila
|
||||||
|
(
|
||||||
|
sifravrste char(2) not null,
|
||||||
|
nazivvrste varchar(18) not null,
|
||||||
|
primary key (sifravrste)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table vozilo
|
||||||
|
(
|
||||||
|
sifravozila char(12) not null,
|
||||||
|
sifravrste char(2) not null references
|
||||||
|
vrstavozila (sifravrste) on update cascade,
|
||||||
|
regbroj char(10),
|
||||||
|
marka char(10),
|
||||||
|
tip char(20),
|
||||||
|
brojsasije char(25),
|
||||||
|
brojmotora char(25),
|
||||||
|
prvaregistracija timestamp,
|
||||||
|
snagamotora decimal(10,2),
|
||||||
|
zapremina integer,
|
||||||
|
nosivost integer,
|
||||||
|
mestazasedenje char(4),
|
||||||
|
karoserija char(25),
|
||||||
|
boja char(20),
|
||||||
|
brojosovina char(1),
|
||||||
|
rokppaparata timestamp,
|
||||||
|
|
||||||
|
primary key (sifravozila)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table vozac
|
||||||
|
(
|
||||||
|
sifravozaca integer not null,
|
||||||
|
ime char(25) not null,
|
||||||
|
kategorije char(5) not null,
|
||||||
|
datumvazenjadozvole timestamp,
|
||||||
|
|
||||||
|
primary key (sifravozaca)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
create table sipanjegoriva
|
||||||
|
(
|
||||||
|
sifrasg integer not null,
|
||||||
|
datum timestamp not null,
|
||||||
|
sifravozila char(12) not null references vozilo
|
||||||
|
(sifravozila) on update cascade,
|
||||||
|
sifravozaca integer not null references vozac
|
||||||
|
(sifravozaca) on update cascade,
|
||||||
|
sifravrstegoriva integer not null references
|
||||||
|
vrstagoriva (sifravrstegoriva) on update cascade,
|
||||||
|
sifraposlovnice char(2) not null references
|
||||||
|
poslovnica (sifraposlovnice) on update cascade,
|
||||||
|
kmsat decimal(9,1),
|
||||||
|
kolicina decimal(10, 2) not null,
|
||||||
|
cena decimal(8,2) not null,
|
||||||
|
pundocepa char(1),
|
||||||
|
check (pundocepa = 'n' or pundocepa = 'd'),
|
||||||
|
|
||||||
|
primary key (sifrasg)
|
||||||
|
);
|
||||||
|
|
||||||
|
create generator gen_gorivo_id;
|
||||||
|
set generator gen_gorivo_id to 1;
|
||||||
|
|
||||||
|
create table popravka
|
||||||
|
(
|
||||||
|
datum timestamp not null,
|
||||||
|
sifravozila char(12) not null references vozilo
|
||||||
|
(sifravozila) on update cascade,
|
||||||
|
sifravozaca integer not null references vozac
|
||||||
|
(sifravozaca) on update cascade,
|
||||||
|
sifraposlovnice char(2) not null references
|
||||||
|
poslovnica (sifraposlovnice) on update cascade,
|
||||||
|
iznos decimal(12,2) not null,
|
||||||
|
opis varchar(200),
|
||||||
|
|
||||||
|
primary key (datum,sifravozila)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
create table registracija
|
||||||
|
(
|
||||||
|
datum timestamp not null,
|
||||||
|
sifravozila char(12) not null references vozilo
|
||||||
|
(sifravozila) on update cascade,
|
||||||
|
cenatehnickog decimal(12,2),
|
||||||
|
cenaosiguranja decimal(12,2),
|
||||||
|
ostalitroskovi decimal(12,2),
|
||||||
|
sifraposlovnice char(2) not null references
|
||||||
|
poslovnica (sifraposlovnice) on update cascade,
|
||||||
|
|
||||||
|
primary key (datum,sifravozila)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table dummy
|
||||||
|
(
|
||||||
|
foobar integer not null primary key,
|
||||||
|
check (foobar = 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into dummy values (1);
|
||||||
|
|
||||||
|
|
||||||
|
/* then, i create few views to make summary report */
|
||||||
|
|
||||||
|
create view apromet(datum, so, vrsta, iznos)
|
||||||
|
as
|
||||||
|
|
||||||
|
select rt.datumtroska, sifraposlovnice, cast
|
||||||
|
(vrt.nazivvrt as varchar
|
||||||
|
(30)), cast (rt.iznos as numeric(18, 2))
|
||||||
|
from rezijskitrosak rt
|
||||||
|
left join vrstart vrt on rt.sifravrt = vrt.sifravrt
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select al.datum, sifraposlovnice, cast ('kancmat'
|
||||||
|
as varchar(30)),
|
||||||
|
cast(sum(alst.kolicina * alst.cena) as numeric(18, 2))
|
||||||
|
from alokacijast alst
|
||||||
|
left join alokacija al on alst.brdok=al.brdok
|
||||||
|
left join roba r on alst.sifrarobe = r.sifrarobe
|
||||||
|
where r.vrstarobe = 'km'
|
||||||
|
group by al.datum, sifraposlovnice
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select al.datum, sifraposlovnice, cast ('hemikalije'
|
||||||
|
as varchar(30)),
|
||||||
|
cast(sum(alst.kolicina * alst.cena) as numeric(18, 2))
|
||||||
|
from alokacijast alst
|
||||||
|
left join alokacija al on alst.brdok=al.brdok
|
||||||
|
left join roba r on alst.sifrarobe = r.sifrarobe
|
||||||
|
where r.vrstarobe = 'he'
|
||||||
|
group by al.datum, sifraposlovnice
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select al.datum, sifraposlovnice, cast ('prehrana'
|
||||||
|
as varchar(30)),
|
||||||
|
cast(sum(alst.kolicina * alst.cena) as numeric(18, 2))
|
||||||
|
from alokacijast alst
|
||||||
|
left join alokacija al on alst.brdok=al.brdok
|
||||||
|
left join roba r on alst.sifrarobe = r.sifrarobe
|
||||||
|
where r.vrstarobe = 'hr'
|
||||||
|
group by al.datum, sifraposlovnice
|
||||||
|
union all
|
||||||
|
|
||||||
|
select pp.datum, sifraposlovnice, cast ('popravke'
|
||||||
|
as varchar(30)),
|
||||||
|
cast(sum(iznos) as numeric(18,2))
|
||||||
|
from popravka pp
|
||||||
|
group by pp.datum, sifraposlovnice
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select rg.datum, sifraposlovnice, cast ('registracije'
|
||||||
|
as varchar
|
||||||
|
(30)), cast(sum(cenatehnickog + cenaosiguranja +
|
||||||
|
ostalitroskovi) as
|
||||||
|
numeric(18,2))
|
||||||
|
from registracija rg
|
||||||
|
group by rg.datum, sifraposlovnice
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select sg.datum, sifraposlovnice, cast ('gorivo' as
|
||||||
|
varchar(30)), cast
|
||||||
|
(sum(kolicina * cena) as numeric(18,2))
|
||||||
|
from sipanjegoriva sg
|
||||||
|
group by sg.datum, sifraposlovnice
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
create view vv(vrsta)
|
||||||
|
as
|
||||||
|
select distinct vrsta
|
||||||
|
from apromet a
|
||||||
|
;
|
||||||
|
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
select distinct fm.code, fm.description, fm.link
|
||||||
|
from fullmenu fm
|
||||||
|
join menu_groups mg on fm.code = mg.menu_id
|
||||||
|
;
|
||||||
|
|
||||||
|
select 'Query from issue 2000-oct-18 passed OK' as msg from rdb$database;
|
||||||
|
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
select
|
||||||
|
vv.vrsta,
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=1),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=2),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=3),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=4),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=5),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=6),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=7),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=8),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=9),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=10),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=11),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta =
|
||||||
|
vv.vrsta and
|
||||||
|
extract(month from ap.datum)=12),
|
||||||
|
(select sum(ap.iznos) from apromet ap where ap.vrsta = vv.vrsta)
|
||||||
|
from vv
|
||||||
|
;
|
||||||
|
|
||||||
|
select 'Query from issue 2002-jul-12 passed OK' as msg from rdb$database;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
MSG Query from issue 2000-oct-18 passed OK
|
||||||
|
MSG Query from issue 2002-jul-12 passed OK
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
53
tests/bugs/core_0474_test.py
Normal file
53
tests/bugs/core_0474_test.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0474
|
||||||
|
# title: Redundant evaluations in COALESCE
|
||||||
|
# decription:
|
||||||
|
# Proper result - only since 2.5.0 :-)
|
||||||
|
# On WI-V2.1.7.18553 Firebird 2.1 result still wrong (curr_gen 4)
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0474
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create generator g1;
|
||||||
|
commit;
|
||||||
|
set list on;
|
||||||
|
select
|
||||||
|
coalesce(
|
||||||
|
nullif(gen_id(g1,1),1),
|
||||||
|
nullif(gen_id(g1,1),2),
|
||||||
|
gen_id(g1,1),
|
||||||
|
nullif(gen_id(g1,1),4),
|
||||||
|
gen_id(g1,1)
|
||||||
|
)
|
||||||
|
as curr_gen
|
||||||
|
from rdb$database;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
CURR_GEN 3
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
140
tests/bugs/core_0475_test.py
Normal file
140
tests/bugs/core_0475_test.py
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0475
|
||||||
|
# title: ORDER BY has no effect
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0475
|
||||||
|
# min_versions: ['2.5.6']
|
||||||
|
# versions: 2.5.6
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.6
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create or alter procedure getChilds as begin end;
|
||||||
|
recreate table test (
|
||||||
|
code integer not null primary key using index test_pk,
|
||||||
|
name varchar(2) not null unique,
|
||||||
|
parent integer,
|
||||||
|
foreign key (parent) references test(code) using index test_fk
|
||||||
|
);
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create or alter procedure getChilds(par integer) returns (code integer,children integer) as
|
||||||
|
begin
|
||||||
|
for
|
||||||
|
select
|
||||||
|
m.code, Min(c.code) from
|
||||||
|
test m
|
||||||
|
left join test c on m.code = c.parent
|
||||||
|
where m.parent = :par or (m.parent is null and :par is null)
|
||||||
|
group by m.code
|
||||||
|
into :code,:children
|
||||||
|
do
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test values (0,'A',null);
|
||||||
|
insert into test values (1,'AA',0);
|
||||||
|
insert into test values (3,'AB',0);
|
||||||
|
insert into test values (4,'AC',0);
|
||||||
|
insert into test values (2,'AD',0);
|
||||||
|
insert into test values (5,'B',null);
|
||||||
|
insert into test values (6,'BA',5);
|
||||||
|
insert into test values (7,'BB',5);
|
||||||
|
insert into test values (8,'BC',5);
|
||||||
|
insert into test values (9,'BD',5);
|
||||||
|
insert into test values (10,'BE',5);
|
||||||
|
insert into test values (11,'BF',5);
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
select *
|
||||||
|
from getChilds(0)
|
||||||
|
inner join test
|
||||||
|
on getChilds.code = test.code
|
||||||
|
order by name
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
select *
|
||||||
|
from getChilds(0)
|
||||||
|
inner join test
|
||||||
|
on getChilds.code = test.code
|
||||||
|
order by name desc
|
||||||
|
;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
CODE 1
|
||||||
|
CHILDREN <null>
|
||||||
|
CODE 1
|
||||||
|
NAME AA
|
||||||
|
PARENT 0
|
||||||
|
|
||||||
|
CODE 3
|
||||||
|
CHILDREN <null>
|
||||||
|
CODE 3
|
||||||
|
NAME AB
|
||||||
|
PARENT 0
|
||||||
|
|
||||||
|
CODE 4
|
||||||
|
CHILDREN <null>
|
||||||
|
CODE 4
|
||||||
|
NAME AC
|
||||||
|
PARENT 0
|
||||||
|
|
||||||
|
CODE 2
|
||||||
|
CHILDREN <null>
|
||||||
|
CODE 2
|
||||||
|
NAME AD
|
||||||
|
PARENT 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CODE 2
|
||||||
|
CHILDREN <null>
|
||||||
|
CODE 2
|
||||||
|
NAME AD
|
||||||
|
PARENT 0
|
||||||
|
|
||||||
|
CODE 4
|
||||||
|
CHILDREN <null>
|
||||||
|
CODE 4
|
||||||
|
NAME AC
|
||||||
|
PARENT 0
|
||||||
|
|
||||||
|
CODE 3
|
||||||
|
CHILDREN <null>
|
||||||
|
CODE 3
|
||||||
|
NAME AB
|
||||||
|
PARENT 0
|
||||||
|
|
||||||
|
CODE 1
|
||||||
|
CHILDREN <null>
|
||||||
|
CODE 1
|
||||||
|
NAME AA
|
||||||
|
PARENT 0
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.6')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
294
tests/bugs/core_0479_test.py
Normal file
294
tests/bugs/core_0479_test.py
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0479
|
||||||
|
# title: Grants overwrite previous rdb$security_classes entries
|
||||||
|
# decription:
|
||||||
|
# Test attempts to create all kinds of objects (<K>) that can be 'target' for GRANT ON <K> statement.
|
||||||
|
# Length of each object is equal to implementation maximum for 2.5.x, 3.0.x and 4.0.
|
||||||
|
# Pairs of objects differ only in last character.
|
||||||
|
# After all, we check that no dupicates are created in rdb$security_classes table for field rdb$security_class.
|
||||||
|
# NOTE-1: for 3.0.x and 4.0 we create objects as quoted, in UTF8, - for additional checking that we have no problem with non-ascii characters.
|
||||||
|
# NOTE-2: max length in 4.0 is 63 utf8 CHARACTERS (not bytes).
|
||||||
|
# Checked on WI-V2.5.7.27027, WI-V3.0.2.32630, WI-T4.0.0.454.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0479
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 3.0, 4.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set bail on;
|
||||||
|
create or alter view v_check as
|
||||||
|
select sc.rdb$security_class, r.obj_type, min(r.obj_name) as obj_1, max(r.obj_name) as obj_2
|
||||||
|
from rdb$security_classes sc
|
||||||
|
left join
|
||||||
|
(
|
||||||
|
|
||||||
|
select r.rdb$relation_name as obj_name, r.rdb$security_class as sec_class, 'table/view' as obj_type
|
||||||
|
from rdb$relations r
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select p.rdb$procedure_name, p.rdb$security_class, 'stored proc'
|
||||||
|
from rdb$procedures p
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select p.rdb$function_name, p.rdb$security_class, 'stored func'
|
||||||
|
from rdb$functions p
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select p.rdb$package_name, p.rdb$security_class, 'package'
|
||||||
|
from rdb$packages p
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select r.rdb$role_name as obj_name, r.rdb$security_class as sec_class, 'role' as obj_type
|
||||||
|
from rdb$roles r
|
||||||
|
|
||||||
|
) r on sc.rdb$security_class = r.sec_class
|
||||||
|
group by 1,2
|
||||||
|
having count(*) > 1
|
||||||
|
;
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
-- tÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêŹ
|
||||||
|
-- tÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêŻ
|
||||||
|
|
||||||
|
recreate table
|
||||||
|
"tÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
(x int)
|
||||||
|
;
|
||||||
|
|
||||||
|
recreate table
|
||||||
|
"TÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
(x int)
|
||||||
|
;
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
create view
|
||||||
|
"vÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
as select * from
|
||||||
|
"tÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
;
|
||||||
|
|
||||||
|
create view
|
||||||
|
"VÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
as select * from
|
||||||
|
"TÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
;
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
create procedure
|
||||||
|
"pÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
as begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
create procedure
|
||||||
|
"PÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
as begin
|
||||||
|
end;
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create function
|
||||||
|
"fÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
returns int
|
||||||
|
as begin
|
||||||
|
return 1;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
create function
|
||||||
|
"FÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
returns int
|
||||||
|
as begin
|
||||||
|
return 1;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
create package
|
||||||
|
"gÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
as begin end
|
||||||
|
^
|
||||||
|
create package
|
||||||
|
"GÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
as begin end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
create role
|
||||||
|
"rÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
;
|
||||||
|
|
||||||
|
create role
|
||||||
|
"RÁÃÀÅĂÂÄĀČĒĻŅŠŪŽ"
|
||||||
|
;
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
SET LIST ON;
|
||||||
|
SET COUNT ON;
|
||||||
|
|
||||||
|
select * from v_check;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
Records affected: 0
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0,<4.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
||||||
|
# version: 4.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_2 = []
|
||||||
|
|
||||||
|
init_script_2 = """"""
|
||||||
|
|
||||||
|
db_2 = db_factory(sql_dialect=3, init=init_script_2)
|
||||||
|
|
||||||
|
test_script_2 = """
|
||||||
|
set bail on;
|
||||||
|
create or alter view v_check as
|
||||||
|
select sc.rdb$security_class, r.obj_type, min(r.obj_name) as obj_1, max(r.obj_name) as obj_2
|
||||||
|
from rdb$security_classes sc
|
||||||
|
left join
|
||||||
|
(
|
||||||
|
|
||||||
|
select r.rdb$relation_name as obj_name, r.rdb$security_class as sec_class, 'table/view' as obj_type
|
||||||
|
from rdb$relations r
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select p.rdb$procedure_name, p.rdb$security_class, 'stored proc'
|
||||||
|
from rdb$procedures p
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select p.rdb$function_name, p.rdb$security_class, 'stored func'
|
||||||
|
from rdb$functions p
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select p.rdb$package_name, p.rdb$security_class, 'package'
|
||||||
|
from rdb$packages p
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
select r.rdb$role_name as obj_name, r.rdb$security_class as sec_class, 'role' as obj_type
|
||||||
|
from rdb$roles r
|
||||||
|
|
||||||
|
) r on sc.rdb$security_class = r.sec_class
|
||||||
|
group by 1,2
|
||||||
|
having count(*) > 1
|
||||||
|
;
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
recreate table
|
||||||
|
"tÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŹ"
|
||||||
|
(x int)
|
||||||
|
;
|
||||||
|
|
||||||
|
recreate table
|
||||||
|
"tÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŻ"
|
||||||
|
(x int)
|
||||||
|
;
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
recreate view
|
||||||
|
"vÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŹ"
|
||||||
|
as select * from
|
||||||
|
"tÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŹ"
|
||||||
|
;
|
||||||
|
|
||||||
|
recreate view
|
||||||
|
"vÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŻ"
|
||||||
|
as select * from
|
||||||
|
"tÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŻ"
|
||||||
|
;
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
create procedure
|
||||||
|
"pÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŹ"
|
||||||
|
as begin
|
||||||
|
end;
|
||||||
|
|
||||||
|
create procedure
|
||||||
|
"pÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŻ"
|
||||||
|
as begin
|
||||||
|
end;
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create function
|
||||||
|
"fÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŹ"
|
||||||
|
returns int
|
||||||
|
as begin
|
||||||
|
return 1;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
create function
|
||||||
|
"fÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŻ"
|
||||||
|
returns int
|
||||||
|
as begin
|
||||||
|
return 1;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
create package
|
||||||
|
"gÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŹ"
|
||||||
|
as begin end
|
||||||
|
^
|
||||||
|
create package
|
||||||
|
"gÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŻ"
|
||||||
|
as begin end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
create role
|
||||||
|
"rÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŹ"
|
||||||
|
;
|
||||||
|
|
||||||
|
create role
|
||||||
|
"rÁÃÀÅĂÂÄĀČĒĻŅŠŪŽĪáéíóúýàèìòùâêîôûãñõäëïöüÿçšδθλξσψωąęłźżњћџăşţŻ"
|
||||||
|
;
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
SET LIST ON;
|
||||||
|
SET COUNT ON;
|
||||||
|
|
||||||
|
select * from v_check;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_2 = isql_act('db_2', test_script_2, substitutions=substitutions_2)
|
||||||
|
|
||||||
|
expected_stdout_2 = """
|
||||||
|
Records affected: 0
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=4.0')
|
||||||
|
def test_2(act_2: Action):
|
||||||
|
act_2.expected_stdout = expected_stdout_2
|
||||||
|
act_2.execute()
|
||||||
|
assert act_2.clean_expected_stdout == act_2.clean_stdout
|
||||||
|
|
42
tests/bugs/core_0480_test.py
Normal file
42
tests/bugs/core_0480_test.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0480
|
||||||
|
# title: Foreign key relation VARCHAR <-> INT
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-480
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_480-21
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table T1 (PK1 INTEGER, COL VARCHAR(10));
|
||||||
|
commit;"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """create table T2 (PK2 INTEGER, FK1 VARCHAR(10), COL VARCHAR(10),
|
||||||
|
foreign key (FK1) references T1 (PK1));
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """Statement failed, SQLSTATE = 42000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-CREATE TABLE T2 failed
|
||||||
|
-could not find UNIQUE or PRIMARY KEY constraint in table T1 with specified columns
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
1052
tests/bugs/core_0501_test.py
Normal file
1052
tests/bugs/core_0501_test.py
Normal file
File diff suppressed because it is too large
Load Diff
47
tests/bugs/core_0507_test.py
Normal file
47
tests/bugs/core_0507_test.py
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0507
|
||||||
|
# title: ambiguous statements return unpredictable results
|
||||||
|
# decription:
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-507
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set planonly;
|
||||||
|
select r.rdb$relation_name, rc.rdb$relation_name, rc.rdb$constraint_type
|
||||||
|
from rdb$relations r left join rdb$relation_constraints rc
|
||||||
|
on r.rdb$relation_name = rc.rdb$relation_name
|
||||||
|
order by rdb$relation_name;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 42702
|
||||||
|
Dynamic SQL Error
|
||||||
|
-SQL error code = -204
|
||||||
|
-Ambiguous field name between a field and a field in the select list with name
|
||||||
|
-RDB$RELATION_NAME
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
78
tests/bugs/core_0521_test.py
Normal file
78
tests/bugs/core_0521_test.py
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0521
|
||||||
|
# title: Permissions are checked case-insensitively
|
||||||
|
# decription:
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-521
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('execute', 'EXECUTE'), ('-Effective user is.*', '')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create user tmp$c0521 password '123';
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create procedure perm
|
||||||
|
as begin
|
||||||
|
end^
|
||||||
|
|
||||||
|
create procedure "PeRm"
|
||||||
|
as begin
|
||||||
|
execute procedure perm;
|
||||||
|
end^
|
||||||
|
|
||||||
|
create procedure "pErM"
|
||||||
|
as begin
|
||||||
|
--execute procedure perm;
|
||||||
|
execute procedure "PeRm";
|
||||||
|
end^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
grant execute on procedure perm to procedure "PeRm";
|
||||||
|
grant execute on procedure "pErM" to user tmp$c0521;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
connect '$(DSN)' user tmp$c0521 password '123';
|
||||||
|
set list on;
|
||||||
|
select current_user as whoami from rdb$database;
|
||||||
|
execute procedure "pErM";
|
||||||
|
|
||||||
|
commit;
|
||||||
|
connect '$(DSN)' user sysdba password 'masterkey';
|
||||||
|
drop user tmp$c0521;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
WHOAMI TMP$C0521
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
no permission for EXECUTE access to PROCEDURE PeRm
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
71
tests/bugs/core_0583_test.py
Normal file
71
tests/bugs/core_0583_test.py
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0583
|
||||||
|
# title: before triggers are firing after checks
|
||||||
|
# decription:
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-583
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('-At trigger.*', '-At trigger')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table test1 (i int, constraint test1_chk check (i between 1 and 5));
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create trigger test1_bi for test1 active before insert position 0 as
|
||||||
|
begin
|
||||||
|
new.i=6;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
|
||||||
|
create trigger test1_bu for test1 active before update position 0 as
|
||||||
|
begin
|
||||||
|
new.i=7;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set count on;
|
||||||
|
insert into test1 values (2);
|
||||||
|
select * from test1;
|
||||||
|
update test1 set i=2 where i = 6;
|
||||||
|
select * from test1;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
Records affected: 0
|
||||||
|
Records affected: 0
|
||||||
|
Records affected: 0
|
||||||
|
Records affected: 0
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 23000
|
||||||
|
Operation violates CHECK constraint TEST1_CHK on view or table TEST1
|
||||||
|
-At trigger 'CHECK_3'
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
144
tests/bugs/core_0606_test.py
Normal file
144
tests/bugs/core_0606_test.py
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0606
|
||||||
|
# title: Tricky role defeats basic SQL security
|
||||||
|
# decription:
|
||||||
|
# CHecked on:
|
||||||
|
# 4.0.0.1635 SS: 1.482s.
|
||||||
|
# 4.0.0.1633 CS: 1.954s.
|
||||||
|
# 3.0.5.33180 SS: 0.976s.
|
||||||
|
# 3.0.5.33178 CS: 1.265s.
|
||||||
|
# 2.5.9.27119 SS: 0.297s.
|
||||||
|
# 2.5.9.27146 SC: 0.306s.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0606
|
||||||
|
# min_versions: ['2.5']
|
||||||
|
# versions: 2.5.6
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.6
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('Statement failed, SQLSTATE = HY000', ''), ('record not found for user:.*', ''), ('read/select', 'SELECT'), ('Data source : Firebird::.*', 'Data source : Firebird::'), ('-At block line: [\\d]+, col: [\\d]+', '-At block line'), ('335545254 : Effective user is.*', '')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set term ^;
|
||||||
|
execute block as
|
||||||
|
begin
|
||||||
|
begin
|
||||||
|
execute statement 'drop role "FOR CVC"';
|
||||||
|
when any do begin end
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
execute statement 'drop role "FOR"';
|
||||||
|
when any do begin end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
^set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
drop user cvc;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate table "t t"(data int);
|
||||||
|
commit;
|
||||||
|
insert into "t t" values(123456);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create user cvc password 'pw';
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create role "FOR CVC";
|
||||||
|
create role "FOR";
|
||||||
|
|
||||||
|
grant "FOR CVC" to user cvc;
|
||||||
|
grant select on table "t t" to "FOR";
|
||||||
|
commit;
|
||||||
|
|
||||||
|
show grants;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
set term ^;
|
||||||
|
execute block returns(who_am_i varchar(31), i_m_playing_role varchar(31)) as
|
||||||
|
begin
|
||||||
|
for
|
||||||
|
execute statement 'select current_user, current_role from rdb$database'
|
||||||
|
on external 'localhost:' || rdb$get_context('SYSTEM','DB_NAME')
|
||||||
|
as user 'cvc' password 'pw' role '"FOR CVC"'
|
||||||
|
into who_am_i, i_m_playing_role
|
||||||
|
do
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
|
||||||
|
execute block returns(data int) as
|
||||||
|
begin
|
||||||
|
for
|
||||||
|
execute statement 'select data from "t t"'
|
||||||
|
on external 'localhost:' || rdb$get_context('SYSTEM','DB_NAME')
|
||||||
|
as user 'cvc' password 'pw' role '"FOR CVC"'
|
||||||
|
into data
|
||||||
|
do
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
-- ||||||||||||||||||||||||||||
|
||||||
|
-- ###################################||| FB 4.0+, SS and SC |||##############################
|
||||||
|
-- ||||||||||||||||||||||||||||
|
||||||
|
-- If we check SS or SC and ExtConnPoolLifeTime > 0 (config parameter FB 4.0+) then current
|
||||||
|
-- DB (bugs.core_NNNN.fdb) will be 'captured' by firebird.exe process and fbt_run utility
|
||||||
|
-- will not able to drop this database at the final point of test.
|
||||||
|
-- Moreover, DB file will be hold until all activity in firebird.exe completed and AFTER this
|
||||||
|
-- we have to wait for <ExtConnPoolLifeTime> seconds after it (discussion and small test see
|
||||||
|
-- in the letter to hvlad and dimitr 13.10.2019 11:10).
|
||||||
|
-- This means that one need to kill all connections to prevent from exception on cleanup phase:
|
||||||
|
-- SQLCODE: -901 / lock time-out on wait transaction / object <this_test_DB> is in use
|
||||||
|
-- #############################################################################################
|
||||||
|
delete from mon$attachments where mon$attachment_id != current_connection;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
drop user cvc;
|
||||||
|
commit;
|
||||||
|
drop role "FOR CVC";
|
||||||
|
drop role "FOR";
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
/* Grant permissions for this database */
|
||||||
|
GRANT SELECT ON t t TO ROLE FOR
|
||||||
|
GRANT FOR CVC TO CVC
|
||||||
|
|
||||||
|
WHO_AM_I CVC
|
||||||
|
I_M_PLAYING_ROLE FOR CVC
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 42000
|
||||||
|
Execute statement error at isc_dsql_prepare :
|
||||||
|
335544352 : no permission for SELECT access to TABLE t t
|
||||||
|
Statement : select data from "t t"
|
||||||
|
Data source : Firebird::localhost:C:\\FBTESTING\\QA\\FBT-REPO\\TMP\\E30.FDB
|
||||||
|
-At block line: 3, col: 7
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.6')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
60
tests/bugs/core_0610_test.py
Normal file
60
tests/bugs/core_0610_test.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0610
|
||||||
|
# title: FIRST is applied before aggregation
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0610
|
||||||
|
# min_versions: ['2.1.7']
|
||||||
|
# versions: 2.1.7
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1.7
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create table A (id integer not null);
|
||||||
|
create table B (id integer not null, A integer not null, v integer);
|
||||||
|
commit;
|
||||||
|
insert into A (id) values (1);
|
||||||
|
insert into A (id) values (2);
|
||||||
|
insert into A (id) values (3);
|
||||||
|
insert into B (id, A, v) values (1, 1, 1);
|
||||||
|
insert into B (id, A, v) values (2, 1, 1);
|
||||||
|
insert into B (id, A, v) values (3, 2, 2);
|
||||||
|
insert into B (id, A, v) values (4, 2, 2);
|
||||||
|
insert into B (id, A, v) values (5, 3, 3);
|
||||||
|
insert into B (id, A, v) values (6, 3, 3);
|
||||||
|
commit;
|
||||||
|
set list on;
|
||||||
|
select first 1 count(*) from a;
|
||||||
|
select first 2 a.id, sum(b.v) from A,B where a.id = b.a
|
||||||
|
group by a.id
|
||||||
|
order by a.id;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
COUNT 3
|
||||||
|
ID 1
|
||||||
|
SUM 2
|
||||||
|
ID 2
|
||||||
|
SUM 4
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1.7')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
49
tests/bugs/core_0611_test.py
Normal file
49
tests/bugs/core_0611_test.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0611
|
||||||
|
# title: SKIP is off by one
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0611
|
||||||
|
# min_versions: ['2.1.7']
|
||||||
|
# versions: 2.1.7
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1.7
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create table A (id integer not null);
|
||||||
|
commit;
|
||||||
|
insert into A (id) values (1);
|
||||||
|
insert into A (id) values (2);
|
||||||
|
insert into A (id) values (3);
|
||||||
|
commit;
|
||||||
|
set list on;
|
||||||
|
select skip 0 id from a order by id;
|
||||||
|
select skip 2 id from a order by id;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
ID 1
|
||||||
|
ID 2
|
||||||
|
ID 3
|
||||||
|
ID 3
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1.7')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
126
tests/bugs/core_0623_test.py
Normal file
126
tests/bugs/core_0623_test.py
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0623
|
||||||
|
# title: ORDER BY on a VIEW turns values in fields into NULL
|
||||||
|
# decription:
|
||||||
|
# 30.10.2019. NB: new datatype in FB 4.0 was introduces: numeric(38,0).
|
||||||
|
# It can lead to additional ident of values when we show them in form "SET LIST ON",
|
||||||
|
# so we have to ignore all internal spaces - see added 'substitution' section below.
|
||||||
|
# Checked on:
|
||||||
|
# 4.0.0.1635 SS: 1.470s.
|
||||||
|
# 3.0.5.33182 SS: 0.981s.
|
||||||
|
# 2.5.9.27146 SC: 0.297s.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0623
|
||||||
|
# min_versions: ['2.1.7']
|
||||||
|
# versions: 2.1.7
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1.7
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('=.*', ''), ('[ \t]+', ' ')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create table p1 (
|
||||||
|
x_p1 numeric(10,0),
|
||||||
|
f_entrada date
|
||||||
|
);
|
||||||
|
|
||||||
|
create view vp1 (
|
||||||
|
x_p1,
|
||||||
|
f_entrada
|
||||||
|
) as
|
||||||
|
select x_p1, f_entrada from p1;
|
||||||
|
|
||||||
|
create table p2 (
|
||||||
|
x_p2 numeric(10,0),
|
||||||
|
p1_x_p1 numeric(10,0),
|
||||||
|
n_one numeric(10,0),
|
||||||
|
n_two numeric(10,0)
|
||||||
|
);
|
||||||
|
|
||||||
|
create view vp2 (
|
||||||
|
p1_x_p1,
|
||||||
|
n_one,
|
||||||
|
n_two
|
||||||
|
) as
|
||||||
|
select p1_x_p1, sum(n_one), sum(n_two)
|
||||||
|
from p2 group by p1_x_p1;
|
||||||
|
|
||||||
|
create view vvp1 (
|
||||||
|
p1_x_p1,
|
||||||
|
f_entrada,
|
||||||
|
n_one,
|
||||||
|
n_two
|
||||||
|
) as
|
||||||
|
select p1.x_p1, p1.f_entrada, p2.n_one, p2.n_two
|
||||||
|
from vp1 p1 left join vp2 p2 on p1.x_p1=p2.p1_x_p1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into p1 values (1,'07/10/2001');
|
||||||
|
insert into p1 values (2,'07/13/2001');
|
||||||
|
insert into p1 values (3,'08/12/2001');
|
||||||
|
|
||||||
|
insert into p2 values (1,1,0,1);
|
||||||
|
insert into p2 values (2,2,1,0);
|
||||||
|
insert into p2 values (3,1,0,1);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
select * from vvp1;
|
||||||
|
select * from vvp1 order by f_entrada;
|
||||||
|
|
||||||
|
insert into p1 values (4,'08/10/2001');
|
||||||
|
insert into p2 values (4,2,0,1);
|
||||||
|
insert into p2 values (5,2,1,1);
|
||||||
|
commit;
|
||||||
|
select * from vvp1;
|
||||||
|
select * from vvp1 order by f_entrada;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
P1_X_P1 F_ENTRADA N_ONE N_TWO
|
||||||
|
===================== =========== ===================== =====================
|
||||||
|
1 2001-07-10 0 2
|
||||||
|
2 2001-07-13 1 0
|
||||||
|
3 2001-08-12 <null> <null>
|
||||||
|
|
||||||
|
|
||||||
|
P1_X_P1 F_ENTRADA N_ONE N_TWO
|
||||||
|
===================== =========== ===================== =====================
|
||||||
|
1 2001-07-10 0 2
|
||||||
|
2 2001-07-13 1 0
|
||||||
|
3 2001-08-12 <null> <null>
|
||||||
|
|
||||||
|
|
||||||
|
P1_X_P1 F_ENTRADA N_ONE N_TWO
|
||||||
|
===================== =========== ===================== =====================
|
||||||
|
1 2001-07-10 0 2
|
||||||
|
2 2001-07-13 2 2
|
||||||
|
3 2001-08-12 <null> <null>
|
||||||
|
4 2001-08-10 <null> <null>
|
||||||
|
|
||||||
|
|
||||||
|
P1_X_P1 F_ENTRADA N_ONE N_TWO
|
||||||
|
===================== =========== ===================== =====================
|
||||||
|
1 2001-07-10 0 2
|
||||||
|
2 2001-07-13 2 2
|
||||||
|
4 2001-08-10 <null> <null>
|
||||||
|
3 2001-08-12 <null> <null>
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1.7')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
57
tests/bugs/core_0625_test.py
Normal file
57
tests/bugs/core_0625_test.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0625
|
||||||
|
# title: Token unknown in simple SELECT with GROUP BY and ORDER BY
|
||||||
|
# decription: getting SQL error code = -104, Token unknown count.
|
||||||
|
# tracker_id: CORE-0625
|
||||||
|
# min_versions: ['2.1.7']
|
||||||
|
# versions: 2.1.7
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1.7
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('\\(+', ''), ('\\)+', '')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
recreate table customers(cust_id int primary key using index customers_pk, country int);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into customers
|
||||||
|
select r.rdb$relation_id, rand()*10
|
||||||
|
from rdb$relations r;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create index customers_country on customers(country);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set planonly;
|
||||||
|
--set explain on;
|
||||||
|
select country, count(country)
|
||||||
|
from customers
|
||||||
|
group by country
|
||||||
|
order by count(country);
|
||||||
|
-- NB: PLAN up to 2.5 contains TWO parenthesis:
|
||||||
|
-- PLAN SORT ((CUSTOMERS ORDER CUSTOMERS_COUNTRY))
|
||||||
|
-- ^^ ^^
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
PLAN SORT CUSTOMERS ORDER CUSTOMERS_COUNTRY
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1.7')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
123
tests/bugs/core_0629_test.py
Normal file
123
tests/bugs/core_0629_test.py
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0629
|
||||||
|
# title: Grouping on derived fields processing NULL data kills IB
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-0629
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
create or alter view v_test as select 1 id from rdb$database;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate table test(
|
||||||
|
id integer not null,
|
||||||
|
dt_beg date,
|
||||||
|
dt_end date,
|
||||||
|
constraint pk_test primary key (id)
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create or alter view v_test as
|
||||||
|
select id, extract(year from dt_beg) - extract(year from dt_end) dy
|
||||||
|
from test;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test values(1, '01.01.2015', null);
|
||||||
|
insert into test values(2, '01.01.2015', '01.01.2015');
|
||||||
|
insert into test values(3, null, null);
|
||||||
|
insert into test values(4, null, null);
|
||||||
|
insert into test values(5, '01.01.2015', '31.12.2014');
|
||||||
|
commit;
|
||||||
|
|
||||||
|
select dy from v_test group by dy;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
create or alter view v_test as select 1 id from rdb$database;
|
||||||
|
commit;
|
||||||
|
recreate table test
|
||||||
|
(
|
||||||
|
a integer,
|
||||||
|
b date,
|
||||||
|
c computed by (extract(day from b)-extract(day from b))
|
||||||
|
);
|
||||||
|
commit;
|
||||||
|
insert into test(a, b) values(1, DATE '2015-05-24');
|
||||||
|
insert into test(a, b) values(1, null);
|
||||||
|
commit;
|
||||||
|
select c from test group by c;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create or alter view v_test as select b-b as dd from test;
|
||||||
|
commit;
|
||||||
|
select dd from v_test group by dd;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create or alter view v_test as select b-0 as dd from test;
|
||||||
|
select dd from v_test group by dd;
|
||||||
|
|
||||||
|
create or alter view v_test
|
||||||
|
as select cast(b as timestamp) as dt from test;
|
||||||
|
select dt from v_test group by dt;
|
||||||
|
|
||||||
|
------------
|
||||||
|
|
||||||
|
create or alter view v_test as select 1 id from rdb$database;
|
||||||
|
commit;
|
||||||
|
recreate table test(a int, b time, c computed by(cast(b as time)));
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test(a, b) values(1, '15:00:29.191');
|
||||||
|
insert into test(a, b) values(1, null);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
select c from test group by c;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
DY <null>
|
||||||
|
DY 0
|
||||||
|
DY 1
|
||||||
|
|
||||||
|
C <null>
|
||||||
|
C 0
|
||||||
|
|
||||||
|
DD <null>
|
||||||
|
DD 0
|
||||||
|
|
||||||
|
DD <null>
|
||||||
|
DD 2015-05-24
|
||||||
|
|
||||||
|
DT <null>
|
||||||
|
DT 2015-05-24 00:00:00.0000
|
||||||
|
|
||||||
|
C <null>
|
||||||
|
C 15:00:29.1910
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
45
tests/bugs/core_0655_test.py
Normal file
45
tests/bugs/core_0655_test.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0655
|
||||||
|
# title: Blob Type 1 compatibility with VarChar
|
||||||
|
# decription: Blob Sub-Type 1 (text) column treated in the same manner as a VarChar column
|
||||||
|
# for assignments, conversions, cast, lower, upper, trim, concatenate and substring
|
||||||
|
# tracker_id: CORE-655
|
||||||
|
# min_versions: ['2.1.0']
|
||||||
|
# versions: 2.1
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table t1 (f1 BLOB SUB_TYPE 1 SEGMENT SIZE 80);
|
||||||
|
insert into t1 values ('Firebird ');
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """select cast(lower(f1) as varchar(20)) lf1, cast(upper(f1) as varchar(20)) uf1, cast(trim(f1)||'2.1' as varchar(20))tf1, cast(f1||'2.1' as varchar(20)) cf1, cast(substring(f1 from 1 for 5) as varchar(20)) sf1 from t1;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """Database: localhost:C:btest mpugs.core_655.fdb, User: SYSDBA
|
||||||
|
SQL>
|
||||||
|
LF1 UF1 TF1 CF1 SF1
|
||||||
|
==================== ==================== ==================== ==================== ====================
|
||||||
|
firebird FIREBIRD Firebird2.1 Firebird 2.1 Fireb
|
||||||
|
|
||||||
|
SQL>"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
39
tests/bugs/core_0696_test.py
Normal file
39
tests/bugs/core_0696_test.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0696
|
||||||
|
# title: User Account maintanance in SQL
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-696
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """CREATE USER alex PASSWORD 'test';
|
||||||
|
COMMIT;
|
||||||
|
ALTER USER alex FIRSTNAME 'Alex' LASTNAME 'Peshkov';
|
||||||
|
COMMIT;
|
||||||
|
ALTER USER alex PASSWORD 'IdQfA';
|
||||||
|
COMMIT;
|
||||||
|
DROP USER alex;
|
||||||
|
COMMIT;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.execute()
|
||||||
|
|
358
tests/bugs/core_0733_test.py
Normal file
358
tests/bugs/core_0733_test.py
Normal file
@ -0,0 +1,358 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0733
|
||||||
|
# title: Compress Data over the Network
|
||||||
|
# decription:
|
||||||
|
# CHANGED 22.12.2019: CODE REDUCTION: REMOVED MEASURES OT TIME.
|
||||||
|
# Results are completely opposite to those which were obtained on snapshots when this test was implenmented (3.0.5.33084, 4.0.0.1347).
|
||||||
|
# Requirement to compress data leads to DEGRADATION of performance when data are stored on local machine, and we have no ability
|
||||||
|
# to change storage when fbt_run is in work (at least for nowadays).
|
||||||
|
# After discuss with dimitr it was decided to remove any logging and its analysis.
|
||||||
|
# We only verify matching of RDB$GET_CONTEXT('SYSTEM', 'WIRE_COMPRESSED') and value that was stored in the firebird.conf
|
||||||
|
# for current check.
|
||||||
|
#
|
||||||
|
# ### NOTE ###
|
||||||
|
# Changed value of parameter WireCompression (in firebird.conf) will be seen by application if it reloads client library.
|
||||||
|
# Reconnect is NOT enough for this. For this reason we use subprocess and call ISQL utility to do above mentioned actions
|
||||||
|
# in new execution context.
|
||||||
|
#
|
||||||
|
# See also tests for:
|
||||||
|
# CORE-5536 - checks that field mon$wire_compressed actually exists in MON$ATTACHMENTS table;
|
||||||
|
# CORE-5913 - checks that built-in rdb$get_context('SYSTEM','WIRE_ENCRYPTED') is avaliable;
|
||||||
|
#
|
||||||
|
# Checked on:
|
||||||
|
# 4.0.0.1693 SS: 3.031s.
|
||||||
|
# 4.0.0.1346 SC: 2.890s.
|
||||||
|
# 4.0.0.1691 CS: 3.678s.
|
||||||
|
# 3.0.5.33215 SS: 1.452s.
|
||||||
|
# 3.0.5.33084 SC: 1.344s.
|
||||||
|
# 3.0.5.33212 CS: 3.175s.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0733
|
||||||
|
# min_versions: ['3.0.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """
|
||||||
|
create domain dm_dump varchar(32700) character set none;
|
||||||
|
recreate table t_log( required_value varchar(5), actual_value varchar(5), elap_ms int );
|
||||||
|
commit;
|
||||||
|
set term ^;
|
||||||
|
create or alter procedure sp_uuid(a_compressable boolean, n_limit int default 1)
|
||||||
|
returns (b dm_dump) as
|
||||||
|
declare g char(16) character set octets;
|
||||||
|
begin
|
||||||
|
if ( a_compressable ) then
|
||||||
|
while (n_limit > 0) do
|
||||||
|
begin
|
||||||
|
g = gen_uuid();
|
||||||
|
b = lpad('',32700, 'AAAAAAAAAAAAAAAA' );
|
||||||
|
n_limit = n_limit - 1;
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
while (n_limit > 0) do
|
||||||
|
begin
|
||||||
|
b = lpad('',32700, gen_uuid() );
|
||||||
|
n_limit = n_limit - 1;
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
# test_script_1
|
||||||
|
#---
|
||||||
|
#
|
||||||
|
# import os
|
||||||
|
# import time as tm
|
||||||
|
# import datetime
|
||||||
|
# from time import time
|
||||||
|
# import re
|
||||||
|
# import shutil
|
||||||
|
# import subprocess
|
||||||
|
# import platform
|
||||||
|
#
|
||||||
|
# from fdb import services
|
||||||
|
#
|
||||||
|
# os.environ["ISC_USER"] = user_name
|
||||||
|
# os.environ["ISC_PASSWORD"] = user_password
|
||||||
|
#
|
||||||
|
# DB_NAME = '$(DATABASE_LOCATION)' + 'bugs.core_0733.fdb'
|
||||||
|
#
|
||||||
|
# DB_PATH = '$(DATABASE_LOCATION)'
|
||||||
|
# U_NAME = user_name
|
||||||
|
# U_PSWD = user_password
|
||||||
|
# NUL_DEVICE = 'nul' if platform.system() == 'Windows' else '/dev/null'
|
||||||
|
#
|
||||||
|
# N_ROWS = 1
|
||||||
|
#
|
||||||
|
# F_SQL_NAME=os.path.join(context['temp_directory'],'tmp_core_0733.sql')
|
||||||
|
#
|
||||||
|
# fb_home = services.connect(host='localhost', user= user_name, password= user_password).get_home_directory()
|
||||||
|
# dts = datetime.datetime.now().strftime("%y%m%d_%H%M%S")
|
||||||
|
# fbconf_bak = fb_home+'firebird_'+dts+'.tmp_0733.bak'
|
||||||
|
# shutil.copy2( fb_home+'firebird.conf', fbconf_bak )
|
||||||
|
#
|
||||||
|
# db_conn.close()
|
||||||
|
#
|
||||||
|
# #--------------------------------------------
|
||||||
|
#
|
||||||
|
# def flush_and_close(file_handle):
|
||||||
|
# # https://docs.python.org/2/library/os.html#os.fsync
|
||||||
|
# # If you're starting with a Python file object f,
|
||||||
|
# # first do f.flush(), and
|
||||||
|
# # then do os.fsync(f.fileno()), to ensure that all internal buffers associated with f are written to disk.
|
||||||
|
# global os
|
||||||
|
#
|
||||||
|
# file_handle.flush()
|
||||||
|
# if file_handle.mode not in ('r', 'rb'):
|
||||||
|
# # otherwise: "OSError: [Errno 9] Bad file descriptor"!
|
||||||
|
# os.fsync(file_handle.fileno())
|
||||||
|
# file_handle.close()
|
||||||
|
#
|
||||||
|
# #--------------------------------------------
|
||||||
|
#
|
||||||
|
# def prepare_fb_conf( fb_home, a_required_value ):
|
||||||
|
#
|
||||||
|
# f_fbconf=open(fb_home+'firebird.conf','r')
|
||||||
|
# fbconf_content=f_fbconf.readlines()
|
||||||
|
# f_fbconf.close()
|
||||||
|
# for i,s in enumerate( fbconf_content ):
|
||||||
|
# if s.lower().lstrip().startswith( 'wirecompression'.lower() ):
|
||||||
|
# fbconf_content[i] = '# <temply commented> ' + s
|
||||||
|
#
|
||||||
|
# fbconf_content.append('\\n# Temporarily added by fbtest, CORE-0733. Should be removed auto:')
|
||||||
|
# fbconf_content.append("\\n#" + '='*30 )
|
||||||
|
# fbconf_content.append('\\nWireCompression = %s' % a_required_value )
|
||||||
|
# fbconf_content.append("\\n#" + '='*30 )
|
||||||
|
# fbconf_content.append("\\n" )
|
||||||
|
#
|
||||||
|
# f_fbconf=open(fb_home+'firebird.conf','w')
|
||||||
|
# f_fbconf.writelines( fbconf_content )
|
||||||
|
# f_fbconf.close()
|
||||||
|
# #------------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# def prepare_sql_4run( required_compression, db_path, n_rows, sql_file_name ):
|
||||||
|
# global os
|
||||||
|
# global U_NAME
|
||||||
|
# global U_PSWD
|
||||||
|
# global NUL_DEVICE
|
||||||
|
#
|
||||||
|
# sql_dump='tmp_core_0733_compression_%(required_compression)s.dump' % ( locals() )
|
||||||
|
#
|
||||||
|
# if os.path.isfile( '%(db_path)s%(sql_dump)s' % (locals()) ):
|
||||||
|
# os.remove( '%(db_path)s%(sql_dump)s' % (locals()) )
|
||||||
|
#
|
||||||
|
# if n_rows is None:
|
||||||
|
# return
|
||||||
|
#
|
||||||
|
# #------------------
|
||||||
|
#
|
||||||
|
# sql_text='''
|
||||||
|
# set list on;
|
||||||
|
#
|
||||||
|
# set term ^;
|
||||||
|
# execute block returns(dts timestamp) as
|
||||||
|
# begin
|
||||||
|
# dts = 'now';
|
||||||
|
# rdb$set_context('USER_SESSION','DTS_BEG', dts);
|
||||||
|
# suspend;
|
||||||
|
# end
|
||||||
|
# ^
|
||||||
|
# set term ;^
|
||||||
|
#
|
||||||
|
# --out %(db_path)s%(sql_dump)s;
|
||||||
|
# out nul;
|
||||||
|
#
|
||||||
|
# set term ^;
|
||||||
|
# execute block returns(b dm_dump) as
|
||||||
|
# begin
|
||||||
|
# /***********
|
||||||
|
# for
|
||||||
|
# execute statement 'select b from sp_uuid( true, %(n_rows)s )'
|
||||||
|
# on external 'localhost:' || rdb$get_context('SYSTEM', 'DB_NAME')
|
||||||
|
# as user '%(U_NAME)s' password '%(U_PSWD)s'
|
||||||
|
# into b
|
||||||
|
# do
|
||||||
|
# suspend;
|
||||||
|
# ***********/
|
||||||
|
# end
|
||||||
|
# ^
|
||||||
|
# set term ;^
|
||||||
|
# out;
|
||||||
|
#
|
||||||
|
# set term ^;
|
||||||
|
# execute block returns(dts timestamp) as
|
||||||
|
# begin
|
||||||
|
# dts = 'now';
|
||||||
|
# rdb$set_context('USER_SESSION','DTS_END', dts);
|
||||||
|
# suspend;
|
||||||
|
# end
|
||||||
|
# ^
|
||||||
|
# set term ;^
|
||||||
|
#
|
||||||
|
# insert into t_log( required_value, actual_value, elap_ms)
|
||||||
|
# values(
|
||||||
|
# upper( '%(required_compression)s' )
|
||||||
|
# ,upper( rdb$get_context('SYSTEM','WIRE_COMPRESSED') )
|
||||||
|
# ,datediff( millisecond
|
||||||
|
# from cast(rdb$get_context('USER_SESSION','DTS_BEG') as timestamp)
|
||||||
|
# to cast(rdb$get_context('USER_SESSION','DTS_END') as timestamp)
|
||||||
|
# )
|
||||||
|
# )
|
||||||
|
# returning required_value, actual_value, elap_ms
|
||||||
|
# ;
|
||||||
|
# commit;
|
||||||
|
# ''' % dict(globals(), **locals())
|
||||||
|
# # ( locals() )
|
||||||
|
#
|
||||||
|
# f_sql=open( sql_file_name, 'w')
|
||||||
|
# f_sql.write( sql_text )
|
||||||
|
# f_sql.close()
|
||||||
|
#
|
||||||
|
# #-------------------------
|
||||||
|
#
|
||||||
|
# # Call for removing dump from disk:
|
||||||
|
# prepare_sql_4run( 'false', DB_PATH, None, None )
|
||||||
|
# prepare_sql_4run( 'true', DB_PATH, None, None )
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# REQUIRED_WIRE_COMPRESSION = 'false'
|
||||||
|
# # ------------------------------------------------------ ###########
|
||||||
|
# # Generate SQL script for running when WireCompression = |||FALSE|||
|
||||||
|
# # ------------------------------------------------------ ###########
|
||||||
|
# prepare_sql_4run( REQUIRED_WIRE_COMPRESSION, DB_PATH, N_ROWS, F_SQL_NAME )
|
||||||
|
#
|
||||||
|
# # ------------------------------------------------------ ###########
|
||||||
|
# # Update content of firebird.conf with WireCompression = |||FALSE|||
|
||||||
|
# # ------------------------------------------------------ ###########
|
||||||
|
# prepare_fb_conf( fb_home, REQUIRED_WIRE_COMPRESSION)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# # --------------------------------------------------------------------------------------
|
||||||
|
# # Launch ISQL in separate context of execution with job to obtain data and log duration
|
||||||
|
# # --------------------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# fn_log = open(os.devnull, 'w')
|
||||||
|
# #fn_log = open( os.path.join(context['temp_directory'],'tmp_0733_with_compression.log'), 'w')
|
||||||
|
# f_isql_obtain_data_err = open( os.path.join(context['temp_directory'],'tmp_0733_obtain_data.err'), 'w')
|
||||||
|
#
|
||||||
|
# subprocess.call( [ context['isql_path'], dsn, "-i", F_SQL_NAME ],
|
||||||
|
# stdout = fn_log,
|
||||||
|
# stderr = f_isql_obtain_data_err
|
||||||
|
# )
|
||||||
|
# fn_log.close()
|
||||||
|
# f_isql_obtain_data_err.close()
|
||||||
|
#
|
||||||
|
# # Call for removing dump from disk:
|
||||||
|
# #prepare_sql_4run( False, DB_PATH, None, None )
|
||||||
|
# #prepare_sql_4run( True, DB_PATH, None, None )
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# # Update content of firebird.conf with WireCompression = true
|
||||||
|
# ##############################################################
|
||||||
|
#
|
||||||
|
# REQUIRED_WIRE_COMPRESSION = 'true'
|
||||||
|
# # ------------------------------------------------------ ###########
|
||||||
|
# # Generate SQL script for running when WireCompression = ||| TRUE|||
|
||||||
|
# # ------------------------------------------------------ ###########
|
||||||
|
# prepare_sql_4run( REQUIRED_WIRE_COMPRESSION, DB_PATH, N_ROWS, F_SQL_NAME )
|
||||||
|
#
|
||||||
|
# # ------------------------------------------------------ ###########
|
||||||
|
# # Update content of firebird.conf with WireCompression = ||| TRUE|||
|
||||||
|
# # ------------------------------------------------------ ###########
|
||||||
|
# prepare_fb_conf( fb_home, REQUIRED_WIRE_COMPRESSION)
|
||||||
|
#
|
||||||
|
# fn_log = open(os.devnull, 'w')
|
||||||
|
# #fn_log = open( os.path.join(context['temp_directory'],'tmp_0733_without_compress.log'), 'w')
|
||||||
|
# f_isql_obtain_data_err = open( os.path.join(context['temp_directory'],'tmp_0733_obtain_data.err'), 'a')
|
||||||
|
#
|
||||||
|
# subprocess.call( [ context['isql_path'], dsn, "-i", F_SQL_NAME ],
|
||||||
|
# stdout = fn_log,
|
||||||
|
# stderr = f_isql_obtain_data_err
|
||||||
|
# )
|
||||||
|
# fn_log.close()
|
||||||
|
# flush_and_close( f_isql_obtain_data_err )
|
||||||
|
#
|
||||||
|
# # Call for removing dump from disk:
|
||||||
|
# #prepare_sql_4run( REQUIRED_WIRE_COMPRESSION, DB_PATH, None, None )
|
||||||
|
#
|
||||||
|
# # RESTORE original config:
|
||||||
|
# ##########################
|
||||||
|
# shutil.copy2( fbconf_bak , fb_home+'firebird.conf')
|
||||||
|
#
|
||||||
|
# sql='''
|
||||||
|
# -- select * from t_log;
|
||||||
|
# -- REQUIRED_VALUE ACTUAL_VALUE ELAP_MS
|
||||||
|
# -- ============== ============ ============
|
||||||
|
# -- FALSE FALSE 2187
|
||||||
|
# -- TRUE TRUE 1782
|
||||||
|
# set list on;
|
||||||
|
# select
|
||||||
|
# result_of_req_compare_to_actual
|
||||||
|
# --,iif( slowest_with_compression < fastest_without_compression,
|
||||||
|
# -- 'EXPECTED: compression was FASTER.',
|
||||||
|
# -- 'POOR. slowest_with_compression=' || slowest_with_compression || ', fastest_without_compression=' || fastest_without_compression
|
||||||
|
# -- ) as result_of_compression_benchmark
|
||||||
|
# from (
|
||||||
|
# select
|
||||||
|
# min( iif( upper(required_value) is distinct from upper(actual_value)
|
||||||
|
# ,coalesce(required_value,'<null>') || coalesce(actual_value,'<null>')
|
||||||
|
# ,'EXPECTED: actual values were equal to required.'
|
||||||
|
# )
|
||||||
|
# ) as result_of_req_compare_to_actual
|
||||||
|
# ,min( iif( upper(required_value) = upper('false'), elap_ms, null ) ) fastest_without_compression
|
||||||
|
# ,max( iif( upper(required_value) = upper('true'), elap_ms, null ) ) slowest_with_compression
|
||||||
|
# from t_log
|
||||||
|
# )
|
||||||
|
# ;
|
||||||
|
# set list off;
|
||||||
|
# --select * from t_log;
|
||||||
|
#
|
||||||
|
# '''
|
||||||
|
# runProgram('isql', [ dsn ], sql)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# # Additional check: STDERR for ISQL must be EMPTY.
|
||||||
|
# ##################################################
|
||||||
|
#
|
||||||
|
# f_list=(f_isql_obtain_data_err,)
|
||||||
|
# for i in range(len(f_list)):
|
||||||
|
# f_name=f_list[i].name
|
||||||
|
# if os.path.getsize(f_name) > 0:
|
||||||
|
# with open( f_name,'r') as f:
|
||||||
|
# for line in f:
|
||||||
|
# print("Unexpected STDERR, file "+f_name+": "+line)
|
||||||
|
#
|
||||||
|
# os.remove(f_isql_obtain_data_err.name)
|
||||||
|
# os.remove(fbconf_bak)
|
||||||
|
# os.remove(F_SQL_NAME)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#---
|
||||||
|
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
RESULT_OF_REQ_COMPARE_TO_ACTUAL EXPECTED: actual values were equal to required.
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
@pytest.mark.xfail
|
||||||
|
def test_1(db_1):
|
||||||
|
pytest.fail("Test not IMPLEMENTED")
|
||||||
|
|
||||||
|
|
304
tests/bugs/core_0769_test.py
Normal file
304
tests/bugs/core_0769_test.py
Normal file
@ -0,0 +1,304 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0769
|
||||||
|
# title: Wildcards/Regular Expressions in WHERE clause - SIMILAR TO predicate
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-769
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """SELECT IIF('ab' SIMILAR TO 'ab|cd|efg','true','false'),'true','''ab'' SIMILAR TO ''ab|cd|efg''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('efg' SIMILAR TO 'ab|cd|efg','true','false'),'true','''efg'' SIMILAR TO ''ab|cd|efg''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a' SIMILAR TO 'ab|cd|efg','true','false'),'false','''a'' SIMILAR TO ''ab|cd|efg''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('' SIMILAR TO 'a*','true','false'),'true',''''' SIMILAR TO ''a*''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a' SIMILAR TO 'a*','true','false'),'true','''a'' SIMILAR TO ''a*''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('aaa' SIMILAR TO 'a*','true','false'),'true','''aaa'' SIMILAR TO ''a*''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('' SIMILAR TO 'a+','true','false'),'false',''''' SIMILAR TO ''a+''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a' SIMILAR TO 'a+','true','false'),'true','''a'' SIMILAR TO ''a+''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('aaa' SIMILAR TO 'a+','true','false'),'true','''aaa'' SIMILAR TO ''a+''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('' SIMILAR TO 'a?','true','false'),'true',''''' SIMILAR TO ''a?''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a' SIMILAR TO 'a?','true','false'),'true','''a'' SIMILAR TO ''a?''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('aaa' SIMILAR TO 'a?','true','false'),'false','''aaa'' SIMILAR TO ''a?''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('' SIMILAR TO 'a{2,}','true','false'),'false',''''' SIMILAR TO ''a{2,}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a' SIMILAR TO 'a{2,}','true','false'),'false','''a'' SIMILAR TO ''a{2,}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('aa' SIMILAR TO 'a{2,}','true','false'),'true','''aa'' SIMILAR TO ''a{2,}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('aaa' SIMILAR TO 'a{2,}','true','false'),'true','''aaa'' SIMILAR TO ''a{2,}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('' SIMILAR TO 'a{2,4}','true','false'),'false',''''' SIMILAR TO ''a{2,4}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a' SIMILAR TO 'a{2,4}','true','false'),'false','''a'' SIMILAR TO ''a{2,4}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('aa' SIMILAR TO 'a{2,4}','true','false'),'true','''aa'' SIMILAR TO ''a{2,4}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('aaa' SIMILAR TO 'a{2,4}','true','false'),'true','''aaa'' SIMILAR TO ''a{2,4}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('aaaa' SIMILAR TO 'a{2,4}','true','false'),'true','''aaaa'' SIMILAR TO ''a{2,4}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('aaaaa' SIMILAR TO 'a{2,4}','true','false'),'false','''aaaaa'' SIMILAR TO ''a{2,4}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('' SIMILAR TO '_','true','false'),'false',''''' SIMILAR TO ''_''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a' SIMILAR TO '_','true','false'),'true','''a'' SIMILAR TO ''_''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('1' SIMILAR TO '_','true','false'),'true','''1'' SIMILAR TO ''_''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a1' SIMILAR TO '_','true','false'),'false','''a1'' SIMILAR TO ''_''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('' SIMILAR TO '%','true','false'),'true',''''' SIMILAR TO ''%''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('az' SIMILAR TO 'a%z','true','false'),'true','''az'' SIMILAR TO ''a%z''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a123z' SIMILAR TO 'a%z','true','false'),'true','''a123z'' SIMILAR TO ''a%z''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('azx' SIMILAR TO 'a%z','true','false'),'false','''azx'' SIMILAR TO ''a%z''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('ab' SIMILAR TO '(ab){2}','true','false'),'false','''ab'' SIMILAR TO ''(ab){2}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('aabb' SIMILAR TO '(ab){2}','true','false'),'false','''aabb'' SIMILAR TO ''(ab){2}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('abab' SIMILAR TO '(ab){2}','true','false'),'true','''abab'' SIMILAR TO ''(ab){2}''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('b' SIMILAR TO '[abc]','true','false'),'true','''b'' SIMILAR TO ''[abc]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('d' SIMILAR TO '[abc]','true','false'),'false','''d'' SIMILAR TO ''[abc]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('9' SIMILAR TO '[0-9]','true','false'),'true','''9'' SIMILAR TO ''[0-9]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('9' SIMILAR TO '[0-8]','true','false'),'false','''9'' SIMILAR TO ''[0-8]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('b' SIMILAR TO '[^abc]','true','false'),'false','''b'' SIMILAR TO ''[^abc]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('d' SIMILAR TO '[^abc]','true','false'),'true','''d'' SIMILAR TO ''[^abc]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('3' SIMILAR TO '[[:DIGIT:]^3]','true','false'),'false','''3'' SIMILAR TO ''[[:DIGIT:]^3]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('4' SIMILAR TO '[[:DIGIT:]^3]','true','false'),'true','''4'' SIMILAR TO ''[[:DIGIT:]^3]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('4' SIMILAR TO '[[:DIGIT:]]','true','false'),'true','''4'' SIMILAR TO ''[[:DIGIT:]]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a' SIMILAR TO '[[:DIGIT:]]','true','false'),'false','''a'' SIMILAR TO ''[[:DIGIT:]]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('4' SIMILAR TO '[^[:DIGIT:]]','true','false'),'false','''4'' SIMILAR TO ''[^[:DIGIT:]]''' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('a' SIMILAR TO '[^[:DIGIT:]]','true','false'),'true','''a'' SIMILAR TO ''[^[:DIGIT:]]''' FROM RDB$DATABASE;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ===========================
|
||||||
|
true true 'ab' SIMILAR TO 'ab|cd|efg'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ============================
|
||||||
|
true true 'efg' SIMILAR TO 'ab|cd|efg'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ==========================
|
||||||
|
false false 'a' SIMILAR TO 'ab|cd|efg'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ==================
|
||||||
|
true true '' SIMILAR TO 'a*'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ===================
|
||||||
|
true true 'a' SIMILAR TO 'a*'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =====================
|
||||||
|
true true 'aaa' SIMILAR TO 'a*'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ==================
|
||||||
|
false false '' SIMILAR TO 'a+'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ===================
|
||||||
|
true true 'a' SIMILAR TO 'a+'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =====================
|
||||||
|
true true 'aaa' SIMILAR TO 'a+'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ==================
|
||||||
|
true true '' SIMILAR TO 'a?'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ===================
|
||||||
|
true true 'a' SIMILAR TO 'a?'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =====================
|
||||||
|
false false 'aaa' SIMILAR TO 'a?'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =====================
|
||||||
|
false false '' SIMILAR TO 'a{2,}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ======================
|
||||||
|
false false 'a' SIMILAR TO 'a{2,}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =======================
|
||||||
|
true true 'aa' SIMILAR TO 'a{2,}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ========================
|
||||||
|
true true 'aaa' SIMILAR TO 'a{2,}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ======================
|
||||||
|
false false '' SIMILAR TO 'a{2,4}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =======================
|
||||||
|
false false 'a' SIMILAR TO 'a{2,4}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ========================
|
||||||
|
true true 'aa' SIMILAR TO 'a{2,4}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =========================
|
||||||
|
true true 'aaa' SIMILAR TO 'a{2,4}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ==========================
|
||||||
|
true true 'aaaa' SIMILAR TO 'a{2,4}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ===========================
|
||||||
|
false false 'aaaaa' SIMILAR TO 'a{2,4}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =================
|
||||||
|
false false '' SIMILAR TO '_'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ==================
|
||||||
|
true true 'a' SIMILAR TO '_'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ==================
|
||||||
|
true true '1' SIMILAR TO '_'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ===================
|
||||||
|
false false 'a1' SIMILAR TO '_'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =================
|
||||||
|
true true '' SIMILAR TO '%'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =====================
|
||||||
|
true true 'az' SIMILAR TO 'a%z'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ========================
|
||||||
|
true true 'a123z' SIMILAR TO 'a%z'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ======================
|
||||||
|
false false 'azx' SIMILAR TO 'a%z'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =========================
|
||||||
|
false false 'ab' SIMILAR TO '(ab){2}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ===========================
|
||||||
|
false false 'aabb' SIMILAR TO '(ab){2}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ===========================
|
||||||
|
true true 'abab' SIMILAR TO '(ab){2}'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ======================
|
||||||
|
true true 'b' SIMILAR TO '[abc]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ======================
|
||||||
|
false false 'd' SIMILAR TO '[abc]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ======================
|
||||||
|
true true '9' SIMILAR TO '[0-9]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ======================
|
||||||
|
false false '9' SIMILAR TO '[0-8]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =======================
|
||||||
|
false false 'b' SIMILAR TO '[^abc]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =======================
|
||||||
|
true true 'd' SIMILAR TO '[^abc]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ==============================
|
||||||
|
false false '3' SIMILAR TO '[[:DIGIT:]^3]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ==============================
|
||||||
|
true true '4' SIMILAR TO '[[:DIGIT:]^3]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ============================
|
||||||
|
true true '4' SIMILAR TO '[[:DIGIT:]]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== ============================
|
||||||
|
false false 'a' SIMILAR TO '[[:DIGIT:]]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =============================
|
||||||
|
false false '4' SIMILAR TO '[^[:DIGIT:]]'
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =============================
|
||||||
|
true true 'a' SIMILAR TO '[^[:DIGIT:]]'
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
75
tests/bugs/core_0790_test.py
Normal file
75
tests/bugs/core_0790_test.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0790
|
||||||
|
# title: Alter view
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-790
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table users (
|
||||||
|
id integer,
|
||||||
|
name varchar(20),
|
||||||
|
passwd varchar(20)
|
||||||
|
);
|
||||||
|
|
||||||
|
create view v_users as
|
||||||
|
select name from users;
|
||||||
|
commit;"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """alter view v_users (id, name, passwd ) as
|
||||||
|
select id, name, passwd from users;
|
||||||
|
commit;
|
||||||
|
show view v_users;
|
||||||
|
create view v_users_name as
|
||||||
|
select name from v_users;
|
||||||
|
commit;
|
||||||
|
alter view v_users (id, name ) as
|
||||||
|
select id, name from users;
|
||||||
|
commit;
|
||||||
|
show view v_users;
|
||||||
|
show view v_users_name;
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """Database: localhost:C:btest2 mpugs.core_0790.fdb, User: SYSDBA
|
||||||
|
SQL> CON> SQL> SQL> ID INTEGER Nullable
|
||||||
|
NAME VARCHAR(20) Nullable
|
||||||
|
PASSWD VARCHAR(20) Nullable
|
||||||
|
View Source:
|
||||||
|
==== ======
|
||||||
|
|
||||||
|
select id, name, passwd from users
|
||||||
|
SQL> CON> SQL> SQL> CON> SQL> SQL> ID INTEGER Nullable
|
||||||
|
NAME VARCHAR(20) Nullable
|
||||||
|
View Source:
|
||||||
|
==== ======
|
||||||
|
|
||||||
|
select id, name from users
|
||||||
|
SQL> NAME VARCHAR(20) Nullable
|
||||||
|
View Source:
|
||||||
|
==== ======
|
||||||
|
|
||||||
|
select name from v_users
|
||||||
|
SQL> SQL> SQL> SQL>"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
98
tests/bugs/core_0800_test.py
Normal file
98
tests/bugs/core_0800_test.py
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0800
|
||||||
|
# title: Easy metadata extract improvements
|
||||||
|
# decription:
|
||||||
|
# Domain DDL: move its CHECK clause from 'create' to 'alter' statement.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-0800
|
||||||
|
# min_versions: ['3.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """
|
||||||
|
set term ^;
|
||||||
|
execute block as
|
||||||
|
begin
|
||||||
|
begin
|
||||||
|
execute statement 'drop domain dm_test';
|
||||||
|
when any do begin end
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
execute statement 'drop collation name_coll';
|
||||||
|
when any do begin end
|
||||||
|
end
|
||||||
|
end^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create collation name_coll for utf8 from unicode no pad case insensitive accent insensitive;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create domain dm_test varchar(20)
|
||||||
|
character set utf8
|
||||||
|
default 'foo'
|
||||||
|
not null
|
||||||
|
check (value in ('foo', 'rio', 'bar'))
|
||||||
|
collate name_coll
|
||||||
|
;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(charset='UTF8', sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
# test_script_1
|
||||||
|
#---
|
||||||
|
# import os
|
||||||
|
# import subprocess
|
||||||
|
#
|
||||||
|
# db_conn.close()
|
||||||
|
#
|
||||||
|
# os.environ["ISC_USER"] = user_name
|
||||||
|
# os.environ["ISC_PASSWORD"] = user_password
|
||||||
|
# db_file="$(DATABASE_LOCATION)bugs.core_0800.fdb"
|
||||||
|
#
|
||||||
|
# f_extract_meta = open( os.path.join(context['temp_directory'],'tmp_meta_0800_init.sql'), 'w')
|
||||||
|
# subprocess.call( [context['isql_path'], dsn, "-x", "-ch", "utf8"],
|
||||||
|
# stdout = f_extract_meta,
|
||||||
|
# stderr = subprocess.STDOUT
|
||||||
|
# )
|
||||||
|
# f_extract_meta.close()
|
||||||
|
#
|
||||||
|
# with open( f_extract_meta.name, 'r') as f:
|
||||||
|
# for line in f:
|
||||||
|
# if 'ALTER DOMAIN' in line.upper():
|
||||||
|
# print( line )
|
||||||
|
#
|
||||||
|
# ###############################
|
||||||
|
# # Cleanup.
|
||||||
|
#
|
||||||
|
# f_list=[]
|
||||||
|
# f_list.append(f_extract_meta)
|
||||||
|
#
|
||||||
|
# for i in range(len(f_list)):
|
||||||
|
# if os.path.isfile(f_list[i].name):
|
||||||
|
# os.remove(f_list[i].name)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#---
|
||||||
|
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
ALTER DOMAIN DM_TEST ADD CONSTRAINT
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
@pytest.mark.xfail
|
||||||
|
def test_1(db_1):
|
||||||
|
pytest.fail("Test not IMPLEMENTED")
|
||||||
|
|
||||||
|
|
172
tests/bugs/core_0805_test.py
Normal file
172
tests/bugs/core_0805_test.py
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0805
|
||||||
|
# title: Privileges of dynamic statements in SP
|
||||||
|
# decription:
|
||||||
|
# Checked on:
|
||||||
|
# 4.0.0.1635 SS: 1.650s.
|
||||||
|
# 4.0.0.1633 CS: 1.714s.
|
||||||
|
# 3.0.5.33180 SS: 0.960s.
|
||||||
|
# 3.0.5.33178 CS: 1.203s.
|
||||||
|
# 2.5.9.27119 SS: 0.324s.
|
||||||
|
# 2.5.9.27146 SC: 0.342s.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-805
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid:
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set wng off;
|
||||||
|
-- Drop old account if it remains from prevoius run:
|
||||||
|
set term ^;
|
||||||
|
execute block as
|
||||||
|
begin
|
||||||
|
begin
|
||||||
|
execute statement 'drop user tmp$c0805_senior' with autonomous transaction;
|
||||||
|
when any do begin end
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
execute statement 'drop user tmp$c0805_junior' with autonomous transaction;
|
||||||
|
when any do begin end
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
execute statement 'drop role tmp$r4junior';
|
||||||
|
when any do begin end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create user tmp$c0805_senior password 'qwe';
|
||||||
|
create user tmp$c0805_junior password '123';
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create role tmp$r4junior;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create or alter procedure sp_test as begin end;
|
||||||
|
|
||||||
|
recreate table test(id int, x int);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test values(1, 100);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create or alter procedure sp_test returns(id int, x int) as
|
||||||
|
begin
|
||||||
|
for select id, x from test into id, x do suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
|
||||||
|
create or alter procedure sp_main(a_usr varchar(31), a_pwd varchar(31), a_role varchar(31) = 'NONE')
|
||||||
|
returns(who_am_i varchar(31), what_is_my_role varchar(31), id int, x int) as
|
||||||
|
begin
|
||||||
|
for
|
||||||
|
execute statement
|
||||||
|
'select current_user, current_role, id, x from sp_test'
|
||||||
|
WITH CALLER PRIVILEGES
|
||||||
|
as user a_usr password a_pwd role a_role
|
||||||
|
into who_am_i, what_is_my_role, id, x
|
||||||
|
do
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
revoke all on all from tmp$c0805_senior;
|
||||||
|
revoke all on all from tmp$c0805_junior;
|
||||||
|
revoke all on all from tmp$r4junior; --restored as uncommented statement, 05.03.2018
|
||||||
|
commit;
|
||||||
|
|
||||||
|
grant select on test to procedure sp_test;
|
||||||
|
grant execute on procedure sp_main to tmp$c0805_senior;
|
||||||
|
grant execute on procedure sp_main to tmp$r4junior;
|
||||||
|
grant execute on procedure sp_test to procedure sp_main;
|
||||||
|
grant tmp$r4junior to tmp$c0805_junior;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
-- result:
|
||||||
|
-- 1) table TEST can be queried only by procedure sp_test;
|
||||||
|
-- 2) procedure sp_test is called only from another procedure - sp_main - and only via ES
|
||||||
|
-- 3) procedure sp_main can be called:
|
||||||
|
-- 2.1) directly by user tmp$c0805_senior (no role required to him);
|
||||||
|
-- 2.2) indirectly by ROLE 'tmp$r4junior' which is granted to user 'tmp$c0805_junior'.
|
||||||
|
|
||||||
|
-- Both these users should be able to see data of table 'TEST':
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
execute block returns(who_am_i varchar(31), what_is_my_role varchar(31), id int, x int) as
|
||||||
|
begin
|
||||||
|
for execute statement ('select * from sp_main( :u, :p)') ( u := 'tmp$c0805_senior', p := 'qwe' )
|
||||||
|
into who_am_i, what_is_my_role, id, x
|
||||||
|
do suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
execute block returns(who_am_i varchar(31), what_is_my_role varchar(31), id int, x int) as
|
||||||
|
begin
|
||||||
|
for execute statement ('select * from sp_main( :u, :p, :r)') ( u := 'tmp$c0805_junior', p := '123', r := 'tmp$r4junior' )
|
||||||
|
into who_am_i, what_is_my_role, id, x
|
||||||
|
do suspend;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
-- ||||||||||||||||||||||||||||
|
||||||
|
-- ###################################||| FB 4.0+, SS and SC |||##############################
|
||||||
|
-- ||||||||||||||||||||||||||||
|
||||||
|
-- If we check SS or SC and ExtConnPoolLifeTime > 0 (config parameter FB 4.0+) then current
|
||||||
|
-- DB (bugs.core_NNNN.fdb) will be 'captured' by firebird.exe process and fbt_run utility
|
||||||
|
-- will not able to drop this database at the final point of test.
|
||||||
|
-- Moreover, DB file will be hold until all activity in firebird.exe completed and AFTER this
|
||||||
|
-- we have to wait for <ExtConnPoolLifeTime> seconds after it (discussion and small test see
|
||||||
|
-- in the letter to hvlad and dimitr 13.10.2019 11:10).
|
||||||
|
-- This means that one need to kill all connections to prevent from exception on cleanup phase:
|
||||||
|
-- SQLCODE: -901 / lock time-out on wait transaction / object <this_test_DB> is in use
|
||||||
|
-- #############################################################################################
|
||||||
|
delete from mon$attachments where mon$attachment_id != current_connection;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
drop user tmp$c0805_senior;
|
||||||
|
drop user tmp$c0805_junior;
|
||||||
|
drop role tmp$r4junior;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
WHO_AM_I TMP$C0805_SENIOR
|
||||||
|
WHAT_IS_MY_ROLE NONE
|
||||||
|
ID 1
|
||||||
|
X 100
|
||||||
|
|
||||||
|
WHO_AM_I TMP$C0805_JUNIOR
|
||||||
|
WHAT_IS_MY_ROLE TMP$R4JUNIOR
|
||||||
|
ID 1
|
||||||
|
X 100
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
46
tests/bugs/core_0824_test.py
Normal file
46
tests/bugs/core_0824_test.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0824
|
||||||
|
# title: accent ignoring collation for unicode
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-824
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, charset='UTF8', sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """SELECT IIF('eeaauoeeeaauo' = 'ÉÈÀÂÛÔÊéèàâûô' COLLATE UNICODE_CI_AI ,'true','false'),'true','''eeaauoeeeaauo'' = ''ÉÈÀÂÛÔÊéèàâûô'' COLLATE UNICODE_CI_AI' FROM RDB$DATABASE;
|
||||||
|
SELECT IIF('EEAAUOEEEAAUO' = 'ÉÈÀÂÛÔÊéèàâûô' COLLATE UNICODE_CI_AI ,'true','false'),'true','''EEAAUOEEEAAUO'' = ''ÉÈÀÂÛÔÊéèàâûô'' COLLATE UNICODE_CI_AI' FROM RDB$DATABASE;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =======================================================
|
||||||
|
true true 'eeaauoeeeaauo' = 'ÉÈÀÂÛÔÊéèàâûô' COLLATE UNICODE_CI_AI
|
||||||
|
|
||||||
|
|
||||||
|
CASE CONSTANT CONSTANT
|
||||||
|
====== ======== =======================================================
|
||||||
|
true true 'EEAAUOEEEAAUO' = 'ÉÈÀÂÛÔÊéèàâûô' COLLATE UNICODE_CI_AI
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
49
tests/bugs/core_0842_test.py
Normal file
49
tests/bugs/core_0842_test.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0842
|
||||||
|
# title: Specific query crashing server
|
||||||
|
# decription: Run the query below twice and the server will crash:
|
||||||
|
#
|
||||||
|
# select
|
||||||
|
# cast('' as varchar(32765)),
|
||||||
|
# cast('' as varchar(32748))
|
||||||
|
# from
|
||||||
|
# rdb$database;
|
||||||
|
# tracker_id: CORE-842
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.1
|
||||||
|
# qmid: bugs.core_842
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
select cast('' as varchar(32765)), cast('' as varchar(32748)) from rdb$database;
|
||||||
|
select cast('' as varchar(32765)), cast('' as varchar(32748)) from rdb$database;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
CAST
|
||||||
|
CAST
|
||||||
|
CAST
|
||||||
|
CAST
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
85
tests/bugs/core_0847_test.py
Normal file
85
tests/bugs/core_0847_test.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0847
|
||||||
|
# title: computed field can't be changed to non-computed using 'alter table alter column type xy'
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-847
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_847
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """
|
||||||
|
recreate table t (
|
||||||
|
f1 varchar(10),
|
||||||
|
f2 varchar(10),
|
||||||
|
cf computed by (f1 || ' - ' || f2)
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into t (f1,f2) values ('0123456789','abcdefghij');
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set blob off;
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
select f1,f2,cf as cf_before_altering from t;
|
||||||
|
|
||||||
|
select b.rdb$field_name field_name, cast(a.rdb$computed_source as varchar(80)) computed_source_before_altering
|
||||||
|
from rdb$fields a
|
||||||
|
join rdb$relation_fields b on a.rdb$field_name = b.rdb$field_source
|
||||||
|
where b.rdb$field_name = upper('CF');
|
||||||
|
|
||||||
|
alter table t alter cf type varchar(30);
|
||||||
|
commit;
|
||||||
|
|
||||||
|
select f1,f2,cf as cf_after_altering from t;
|
||||||
|
|
||||||
|
select b.rdb$field_name field_name, cast(a.rdb$computed_source as varchar(80)) computed_source_after_altering
|
||||||
|
from rdb$fields a
|
||||||
|
join rdb$relation_fields b on a.rdb$field_name = b.rdb$field_source
|
||||||
|
where b.rdb$field_name = upper('CF');
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
F1 0123456789
|
||||||
|
F2 abcdefghij
|
||||||
|
CF_BEFORE_ALTERING 0123456789 - abcdefghij
|
||||||
|
|
||||||
|
FIELD_NAME CF
|
||||||
|
COMPUTED_SOURCE_BEFORE_ALTERING (f1 || ' - ' || f2)
|
||||||
|
|
||||||
|
F1 0123456789
|
||||||
|
F2 abcdefghij
|
||||||
|
CF_AFTER_ALTERING 0123456789 - abcdefghij
|
||||||
|
|
||||||
|
FIELD_NAME CF
|
||||||
|
COMPUTED_SOURCE_AFTER_ALTERING (f1 || ' - ' || f2)
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 42000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER TABLE T failed
|
||||||
|
-Cannot add or remove COMPUTED from column CF
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
41
tests/bugs/core_0850_test.py
Normal file
41
tests/bugs/core_0850_test.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0850
|
||||||
|
# title: DYN allows to set defaults for computed fields when altering a field
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-850
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_850
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table t2(a int, b int computed by (00));
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """alter table t2 alter b set default 5;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """Statement failed, SQLSTATE = 42000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-ALTER TABLE T2 failed
|
||||||
|
-Cannot add or remove COMPUTED from column B
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
41
tests/bugs/core_0851_test.py
Normal file
41
tests/bugs/core_0851_test.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0851
|
||||||
|
# title: Field can be used multiple times in multi-segment index definition
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-851
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_851-250
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table t (i integer);
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """create index ti on t(i,i);
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """Statement failed, SQLSTATE = 42000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-CREATE INDEX TI failed
|
||||||
|
-Field I cannot be used twice in index TI
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
40
tests/bugs/core_0852_test.py
Normal file
40
tests/bugs/core_0852_test.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0852
|
||||||
|
# title: substring(current_user from 4) fails
|
||||||
|
# decription: select substring( current_user from 4) from rdb$database;
|
||||||
|
# fails on string truncation
|
||||||
|
# tracker_id: CORE-852
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.0
|
||||||
|
# qmid: bugs.core_852
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
select substring(current_user from 4) from rdb$database;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
SUBSTRING DBA
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
43
tests/bugs/core_0855_test.py
Normal file
43
tests/bugs/core_0855_test.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0855
|
||||||
|
# title: Aggregates in the WHERE clause vs derived tables
|
||||||
|
# decription: Aggregates in the WHERE clause vs derived tables
|
||||||
|
# tracker_id: CORE-855
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_855-250
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """select * from (
|
||||||
|
select rdb$relation_id
|
||||||
|
from rdb$database
|
||||||
|
)
|
||||||
|
where sum(rdb$relation_id) = 0;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """Statement failed, SQLSTATE = 42000
|
||||||
|
Dynamic SQL Error
|
||||||
|
-SQL error code = -104
|
||||||
|
-Cannot use an aggregate or window function in a WHERE clause, use HAVING (for aggregate only) instead
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
79
tests/bugs/core_0856_test.py
Normal file
79
tests/bugs/core_0856_test.py
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0856
|
||||||
|
# title: Unable to set FName, MName, LName fields in security to blank
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-856
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_856
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create or alter user tmp$c0856 password '123'
|
||||||
|
firstname '....:....1....:....2....:....3..'
|
||||||
|
middlename '....:....1....:....2....:....3..'
|
||||||
|
lastname '....:....1....:....2....:....3..'
|
||||||
|
;
|
||||||
|
commit;
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
select sec$user_name, sec$first_name, sec$middle_name, sec$last_name
|
||||||
|
from sec$users where upper(sec$user_name)=upper('tmp$c0856');
|
||||||
|
|
||||||
|
alter user tmp$c0856
|
||||||
|
firstname ''
|
||||||
|
middlename _ascii x'09'
|
||||||
|
lastname _ascii x'0A'
|
||||||
|
;
|
||||||
|
|
||||||
|
commit;
|
||||||
|
select
|
||||||
|
sec$user_name,
|
||||||
|
octet_length(sec$first_name),
|
||||||
|
octet_length(sec$middle_name),
|
||||||
|
octet_length(sec$last_name),
|
||||||
|
ascii_val(left(sec$first_name,1)),
|
||||||
|
ascii_val(left(sec$middle_name,1)),
|
||||||
|
ascii_val(left(sec$last_name,1))
|
||||||
|
from sec$users where upper(sec$user_name)=upper('tmp$c0856');
|
||||||
|
commit;
|
||||||
|
|
||||||
|
drop user tmp$c0856;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
SEC$USER_NAME TMP$C0856
|
||||||
|
SEC$FIRST_NAME ....:....1....:....2....:....3..
|
||||||
|
SEC$MIDDLE_NAME ....:....1....:....2....:....3..
|
||||||
|
SEC$LAST_NAME ....:....1....:....2....:....3..
|
||||||
|
|
||||||
|
SEC$USER_NAME TMP$C0856
|
||||||
|
OCTET_LENGTH <null>
|
||||||
|
OCTET_LENGTH 1
|
||||||
|
OCTET_LENGTH 1
|
||||||
|
ASCII_VAL <null>
|
||||||
|
ASCII_VAL 9
|
||||||
|
ASCII_VAL 10
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
94
tests/bugs/core_0857_test.py
Normal file
94
tests/bugs/core_0857_test.py
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0857
|
||||||
|
# title: Containing not working correctly
|
||||||
|
# decription:
|
||||||
|
# Could not find build 2.0 RC3.
|
||||||
|
# Checked on:
|
||||||
|
# 4.0.0.1713 SS: 1.625s.
|
||||||
|
# 4.0.0.1346 SC: 1.675s.
|
||||||
|
# 3.0.5.33218 SS: 1.000s.
|
||||||
|
# 3.0.5.33084 SC: 0.890s.
|
||||||
|
# 2.5.9.27149 SC: 0.266s.
|
||||||
|
#
|
||||||
|
# 02-mar-2021. Re-implemented in ordeer to have ability to run this test on Linux.
|
||||||
|
# We run 'init_script' using charset = utf8 but then run separate ISQL-process
|
||||||
|
# with request to establish connection using charset = win1252.
|
||||||
|
#
|
||||||
|
# Checked on:
|
||||||
|
# * Windows: 4.0.0.2377, 3.0.8.33420, 2.5.9.27152
|
||||||
|
# * Linux: 4.0.0.2377, 3.0.8.33415
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-857
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """
|
||||||
|
create collation test_coll_ci_ai for win1252 from WIN_PTBR
|
||||||
|
case insensitive
|
||||||
|
accent insensitive
|
||||||
|
;
|
||||||
|
|
||||||
|
create table test (
|
||||||
|
id int,
|
||||||
|
f01 varchar(100),
|
||||||
|
f02 varchar(100) collate WIN_PTBR
|
||||||
|
);
|
||||||
|
|
||||||
|
insert into test(id, f01) values(1, 'IHF|groß|850xC|P1');
|
||||||
|
update test set f02=f01;
|
||||||
|
commit;
|
||||||
|
create view v_test as
|
||||||
|
select octet_length(t.f01) - octet_length(replace(t.f01, 'ß', '')) as "octet_length diff:" from test t;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(charset='WIN1252', sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
# test_script_1
|
||||||
|
#---
|
||||||
|
#
|
||||||
|
# sql_cmd='''
|
||||||
|
# set names win1252;
|
||||||
|
# connect '%(dsn)s' user '%(user_name)s' password '%(user_password)s';
|
||||||
|
# set list on;
|
||||||
|
# select c.rdb$character_set_name as connection_cset
|
||||||
|
# from mon$attachments a
|
||||||
|
# join rdb$character_sets c on a.mon$character_set_id = c.rdb$character_set_id
|
||||||
|
# where a.mon$attachment_id = current_connection;
|
||||||
|
#
|
||||||
|
# select t.id as "test_1 result:" from rdb$database r left join test t on t.f01 not containing 'P1' and t.f01 like 'IHF|gro_|850_C|P1';
|
||||||
|
# select t.id as "test_2 result:" from rdb$database r left join test t on t.f01 containing 'P1' and t.f01 like 'IHF|gro_|850_C|P1';
|
||||||
|
# select t.id as "ci_ai result:" from rdb$database r left join test t on lower(t.f02) = upper(t.f02);
|
||||||
|
# select t.id as "between result:" from rdb$database r left join test t on lower(t.f01) between lower(t.f02) and upper(t.f02);
|
||||||
|
# select * from v_test;
|
||||||
|
# ''' % dict(globals(), **locals())
|
||||||
|
# runProgram( 'isql', [ '-q' ], sql_cmd)
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#---
|
||||||
|
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
CONNECTION_CSET WIN1252
|
||||||
|
test_1 result: <null>
|
||||||
|
test_2 result: 1
|
||||||
|
ci_ai result: 1
|
||||||
|
between result: 1
|
||||||
|
octet_length diff: 1
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
@pytest.mark.xfail
|
||||||
|
def test_1(db_1):
|
||||||
|
pytest.fail("Test not IMPLEMENTED")
|
||||||
|
|
||||||
|
|
107
tests/bugs/core_0858_test.py
Normal file
107
tests/bugs/core_0858_test.py
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0858
|
||||||
|
# title: Server crash when using UDF
|
||||||
|
# decription:
|
||||||
|
# Checked on:
|
||||||
|
# 2.5.9.27126: OK, 0.594s.
|
||||||
|
# 3.0.5.33086: OK, 1.343s.
|
||||||
|
# 4.0.0.1378: OK, 6.969s.
|
||||||
|
#
|
||||||
|
# 24.01.2019.
|
||||||
|
# Disabled this test to be run on FB 4.0: added record to '%FBT_REPO% ests\\qa4x-exclude-list.txt'.
|
||||||
|
#
|
||||||
|
# UDF usage is deprecated in FB 4+, see: ".../doc/README.incompatibilities.3to4.txt".
|
||||||
|
# Functions div, frac, dow, sdow, getExactTimestampUTC and isLeapYear got safe replacement
|
||||||
|
# in UDR library "udf_compat", see it in folder: ../plugins/udr/
|
||||||
|
#
|
||||||
|
# UDF function 'sright' has direct built-in analog 'right', there is no UDR function for it.
|
||||||
|
#
|
||||||
|
# tracker_id: CORE-858
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0, 4.0
|
||||||
|
# qmid: bugs.core_858
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set bail on;
|
||||||
|
declare external function sright
|
||||||
|
varchar(100) by descriptor, smallint,
|
||||||
|
varchar(100) by descriptor returns parameter 3
|
||||||
|
entry_point 'right' module_name 'fbudf';
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set list on;
|
||||||
|
select
|
||||||
|
rdb$function_name
|
||||||
|
,rdb$function_type
|
||||||
|
,rdb$module_name
|
||||||
|
,rdb$entrypoint
|
||||||
|
,rdb$return_argument
|
||||||
|
,rdb$system_flag
|
||||||
|
,rdb$legacy_flag
|
||||||
|
from rdb$functions where upper(rdb$function_name) = upper('sright');
|
||||||
|
|
||||||
|
select sright('qwerty', 2) as sright_result from rdb$database;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
drop external function sright;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
RDB$FUNCTION_NAME SRIGHT
|
||||||
|
RDB$FUNCTION_TYPE <null>
|
||||||
|
RDB$MODULE_NAME fbudf
|
||||||
|
RDB$ENTRYPOINT right
|
||||||
|
RDB$RETURN_ARGUMENT 3
|
||||||
|
RDB$SYSTEM_FLAG 0
|
||||||
|
RDB$LEGACY_FLAG 1
|
||||||
|
|
||||||
|
SRIGHT_RESULT ty
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0,<4.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
||||||
|
# version: 4.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_2 = []
|
||||||
|
|
||||||
|
init_script_2 = """"""
|
||||||
|
|
||||||
|
db_2 = db_factory(sql_dialect=3, init=init_script_2)
|
||||||
|
|
||||||
|
test_script_2 = """
|
||||||
|
-- This section was intentionally left empty.
|
||||||
|
-- No message should be in expected_* sections.
|
||||||
|
-- It is STRONGLY RECOMMENDED to add this ticket
|
||||||
|
-- in the 'excluded-list file:
|
||||||
|
-- %FBT_REPO% ests\\qa4x-exclude-list.txt
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_2 = isql_act('db_2', test_script_2, substitutions=substitutions_2)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.version('>=4.0')
|
||||||
|
def test_2(act_2: Action):
|
||||||
|
act_2.execute()
|
||||||
|
|
65
tests/bugs/core_0859_test.py
Normal file
65
tests/bugs/core_0859_test.py
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0859
|
||||||
|
# title: Sorting is allowed for blobs and arrays
|
||||||
|
# decription: This one is supposed to fail for now, as we restored the legacy behavior until we're able to implement DISTINCT for blobs properly
|
||||||
|
# tracker_id: CORE-859
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 9.1
|
||||||
|
# qmid: bugs.core_859
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 9.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table t (i integer, b blob sub_type text, a integer [5]);
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
# test_script_1
|
||||||
|
#---
|
||||||
|
# c = db_conn.cursor()
|
||||||
|
# try:
|
||||||
|
# c.prep('select * from t order by b')
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
# else:
|
||||||
|
# print ('Test Failed in case 1')
|
||||||
|
#
|
||||||
|
# try:
|
||||||
|
# c.prep('select * from t order by a')
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
# else:
|
||||||
|
# print ('Test Failed in case 2')
|
||||||
|
#
|
||||||
|
# try:
|
||||||
|
# c.prep('select b, count(*) from t group by b')
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
# else:
|
||||||
|
# print ('Test Failed in case 3')
|
||||||
|
#
|
||||||
|
# try:
|
||||||
|
# c.prep('select a, count(*) from t group by a')
|
||||||
|
# except:
|
||||||
|
# pass
|
||||||
|
# else:
|
||||||
|
# print ('Test Failed in case 4')
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#---
|
||||||
|
#act_1 = python_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.version('>=9.1')
|
||||||
|
@pytest.mark.xfail
|
||||||
|
def test_1(db_1):
|
||||||
|
pytest.fail("Test not IMPLEMENTED")
|
||||||
|
|
||||||
|
|
53
tests/bugs/core_0866_test.py
Normal file
53
tests/bugs/core_0866_test.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0866
|
||||||
|
# title: Removing a NOT NULL constraint is not visible until reconnect
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-866
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_866
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """
|
||||||
|
recreate table test (
|
||||||
|
id integer not null,
|
||||||
|
col varchar(20) not null
|
||||||
|
);
|
||||||
|
insert into test (id, col) values (1, 'data');
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
update rdb$relation_fields
|
||||||
|
set rdb$null_flag = null
|
||||||
|
where (rdb$field_name = upper('col')) and (rdb$relation_name = upper('test'));
|
||||||
|
commit;
|
||||||
|
|
||||||
|
update test set col = null where id = 1;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 42000
|
||||||
|
UPDATE operation is not allowed for system table RDB$RELATION_FIELDS
|
||||||
|
Statement failed, SQLSTATE = 23000
|
||||||
|
validation error for column "TEST"."COL", value "*** null ***"
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
38
tests/bugs/core_0870_test.py
Normal file
38
tests/bugs/core_0870_test.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0870
|
||||||
|
# title: Engine crashes while trying to backup a logically corrupt db
|
||||||
|
# decription: This test works only for fb 2.1-2.5 and was converted to dummy one for 3.0 as it needs specificaly corrupted database. We don't have such database with ODS 12 required by fb 3.0+
|
||||||
|
# tracker_id: CORE-870
|
||||||
|
# min_versions: ['2.1']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_870
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on; select 'Extracted .fdb file has not supported ODS for using on Firebird 3.0' as msg from rdb$database;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
MSG Extracted .fdb file has not supported ODS for using on Firebird 3.0
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
50
tests/bugs/core_0871_test.py
Normal file
50
tests/bugs/core_0871_test.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0871
|
||||||
|
# title: Incorrect handling of null within view - returns 0
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-871
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.1
|
||||||
|
# qmid: bugs.core_871
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """CREATE DOMAIN D INTEGER NOT NULL;
|
||||||
|
CREATE TABLE T (A D);
|
||||||
|
CREATE TABLE U (B D);
|
||||||
|
CREATE VIEW V (A, B) AS
|
||||||
|
SELECT T.A, U.B FROM T LEFT JOIN U ON (T.A = U.B);
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
INSERT INTO T VALUES(1);
|
||||||
|
COMMIT;
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """SELECT * FROM V;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """A B
|
||||||
|
============ ============
|
||||||
|
1 <null>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
74
tests/bugs/core_0878_test.py
Normal file
74
tests/bugs/core_0878_test.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0878
|
||||||
|
# title: problem when dropping column that is a primary key
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-878
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.1
|
||||||
|
# qmid: bugs.core_878
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """create table pk1 (i1 integer not null, i2 integer);
|
||||||
|
alter table pk1 add primary key (i1);
|
||||||
|
commit;
|
||||||
|
show table pk1;
|
||||||
|
alter table pk1 drop i1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create table pk2 (i1 integer not null, i2 integer);
|
||||||
|
alter table pk2 add constraint pk2_pk primary key (i1);
|
||||||
|
commit;
|
||||||
|
show table pk2;
|
||||||
|
alter table pk2 drop i1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
create table pk3 (i1 integer not null primary key, i2 integer);
|
||||||
|
commit;
|
||||||
|
show table pk3;
|
||||||
|
alter table pk3 drop i1;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
show table pk1;
|
||||||
|
|
||||||
|
show table pk2;
|
||||||
|
|
||||||
|
show table pk3;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """I1 INTEGER Not Null
|
||||||
|
I2 INTEGER Nullable
|
||||||
|
CONSTRAINT INTEG_2:
|
||||||
|
Primary key (I1)
|
||||||
|
I1 INTEGER Not Null
|
||||||
|
I2 INTEGER Nullable
|
||||||
|
CONSTRAINT PK2_PK:
|
||||||
|
Primary key (I1)
|
||||||
|
I1 INTEGER Not Null
|
||||||
|
I2 INTEGER Nullable
|
||||||
|
CONSTRAINT INTEG_5:
|
||||||
|
Primary key (I1)
|
||||||
|
I2 INTEGER Nullable
|
||||||
|
I2 INTEGER Nullable
|
||||||
|
I2 INTEGER Nullable
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
46
tests/bugs/core_0879_test.py
Normal file
46
tests/bugs/core_0879_test.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0879
|
||||||
|
# title: Dependencies are not cleared when creation of expression index fails
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-879
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5
|
||||||
|
# qmid:
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
create table tab ( a varchar(10000) );
|
||||||
|
commit;
|
||||||
|
create index ix on tab computed by (upper(a));
|
||||||
|
drop table tab;
|
||||||
|
commit;
|
||||||
|
show table tab;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 42000
|
||||||
|
unsuccessful metadata update
|
||||||
|
-key size exceeds implementation restriction for index "IX"
|
||||||
|
There is no table TAB in this database
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
|
49
tests/bugs/core_0881_test.py
Normal file
49
tests/bugs/core_0881_test.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0881
|
||||||
|
# title: Singleton isn't respected in COMPUTED BY expressions
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-881
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.5.0
|
||||||
|
# qmid: bugs.core_881-250
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """create table t1 (n integer);
|
||||||
|
create table t2 (n integer, c computed by ((select n from t1)));
|
||||||
|
|
||||||
|
insert into t1 values (1);
|
||||||
|
insert into t1 values (2);
|
||||||
|
insert into t2 values (1);
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """select * from t2;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """N C
|
||||||
|
============ ============
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """Statement failed, SQLSTATE = 21000
|
||||||
|
multiple rows in singleton select
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
141
tests/bugs/core_0883_test.py
Normal file
141
tests/bugs/core_0883_test.py
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0883
|
||||||
|
# title: The built-in BLR printer doesn't support all FB2 features
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-883
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_883
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('RDB\\$PROCEDURE_BLR.*', '')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(from_backup='core0883-ods12.fbk', init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set list on;
|
||||||
|
set blob all;
|
||||||
|
select rdb$procedure_blr
|
||||||
|
from rdb$procedures
|
||||||
|
where rdb$procedure_name = upper('sp1');
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
RDB$PROCEDURE_BLR 1a:f1
|
||||||
|
blr_version5,
|
||||||
|
blr_begin,
|
||||||
|
blr_message, 1, 1,0,
|
||||||
|
blr_short, 0,
|
||||||
|
blr_begin,
|
||||||
|
blr_declare, 0,0, blr_sql_time,
|
||||||
|
blr_assignment,
|
||||||
|
blr_null,
|
||||||
|
blr_variable, 0,0,
|
||||||
|
blr_declare, 1,0, blr_timestamp,
|
||||||
|
blr_assignment,
|
||||||
|
blr_null,
|
||||||
|
blr_variable, 1,0,
|
||||||
|
blr_declare, 2,0, blr_long, 0,
|
||||||
|
blr_assignment,
|
||||||
|
blr_null,
|
||||||
|
blr_variable, 2,0,
|
||||||
|
blr_declare, 3,0, blr_blob2, 0,0, 0,0,
|
||||||
|
blr_assignment,
|
||||||
|
blr_null,
|
||||||
|
blr_variable, 3,0,
|
||||||
|
blr_declare, 4,0, blr_blob2, 0,0, 0,0,
|
||||||
|
blr_assignment,
|
||||||
|
blr_null,
|
||||||
|
blr_variable, 4,0,
|
||||||
|
blr_dcl_cursor, 0,0,
|
||||||
|
blr_rse, 1,
|
||||||
|
blr_relation2, 14, 'R','D','B','$','P','R','O','C','E','D','U','R','E','S',
|
||||||
|
8, 'C','_','S','T','T','M',32,'P', 0,
|
||||||
|
blr_end,
|
||||||
|
3,0,
|
||||||
|
blr_derived_expr, 1, 0,
|
||||||
|
blr_field, 0, 16, 'R','D','B','$','P','R','O','C','E','D','U','R','E','_','I','D',
|
||||||
|
blr_derived_expr, 1, 0,
|
||||||
|
blr_field, 0, 20, 'R','D','B','$','P','R','O','C','E','D','U','R','E','_','S','O','U','R','C','E',
|
||||||
|
blr_derived_expr, 1, 0,
|
||||||
|
blr_field, 0, 17, 'R','D','B','$','P','R','O','C','E','D','U','R','E','_','B','L','R',
|
||||||
|
blr_stall,
|
||||||
|
blr_label, 0,
|
||||||
|
blr_begin,
|
||||||
|
blr_begin,
|
||||||
|
blr_assignment,
|
||||||
|
blr_current_time2, 3,
|
||||||
|
blr_variable, 0,0,
|
||||||
|
blr_assignment,
|
||||||
|
blr_current_timestamp,
|
||||||
|
blr_variable, 1,0,
|
||||||
|
blr_cursor_stmt, 0, 0,0,
|
||||||
|
|
||||||
|
blr_begin,
|
||||||
|
blr_end,
|
||||||
|
blr_label, 1,
|
||||||
|
blr_loop,
|
||||||
|
blr_begin,
|
||||||
|
blr_if,
|
||||||
|
blr_eql,
|
||||||
|
blr_literal, blr_long, 0, 1,0,0,0,
|
||||||
|
blr_literal, blr_long, 0, 1,0,0,0,
|
||||||
|
blr_begin,
|
||||||
|
blr_begin,
|
||||||
|
blr_cursor_stmt, 2, 0,0,
|
||||||
|
|
||||||
|
blr_begin,
|
||||||
|
blr_assignment,
|
||||||
|
blr_field, 0, 16, 'R','D','B','$','P','R','O','C','E','D','U','R','E','_','I','D',
|
||||||
|
blr_variable, 2,0,
|
||||||
|
blr_assignment,
|
||||||
|
blr_field, 0, 20, 'R','D','B','$','P','R','O','C','E','D','U','R','E','_','S','O','U','R','C','E',
|
||||||
|
blr_variable, 3,0,
|
||||||
|
blr_assignment,
|
||||||
|
blr_field, 0, 17, 'R','D','B','$','P','R','O','C','E','D','U','R','E','_','B','L','R',
|
||||||
|
blr_variable, 4,0,
|
||||||
|
blr_end,
|
||||||
|
blr_if,
|
||||||
|
blr_eql,
|
||||||
|
blr_internal_info,
|
||||||
|
blr_literal, blr_long, 0, 5,0,0,0,
|
||||||
|
blr_literal, blr_long, 0, 0,0,0,0,
|
||||||
|
blr_leave, 1,
|
||||||
|
blr_end,
|
||||||
|
blr_end,
|
||||||
|
blr_end,
|
||||||
|
blr_leave, 1,
|
||||||
|
blr_end,
|
||||||
|
blr_cursor_stmt, 1, 0,0,
|
||||||
|
|
||||||
|
blr_begin,
|
||||||
|
blr_end,
|
||||||
|
blr_end,
|
||||||
|
blr_end,
|
||||||
|
blr_end,
|
||||||
|
blr_send, 1,
|
||||||
|
blr_begin,
|
||||||
|
blr_assignment,
|
||||||
|
blr_literal, blr_short, 0, 0,0,
|
||||||
|
blr_parameter, 1, 0,0,
|
||||||
|
blr_end,
|
||||||
|
blr_end,
|
||||||
|
blr_eoc
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
182
tests/bugs/core_0885_test.py
Normal file
182
tests/bugs/core_0885_test.py
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0885
|
||||||
|
# title: It is impossible to take away rights on update of a column
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-885
|
||||||
|
# min_versions: ['3.0']
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid:
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('-Effective user is.*', '')]
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
set wng off;
|
||||||
|
set list on;
|
||||||
|
|
||||||
|
create or alter user john_senior password 'sen' revoke admin role;
|
||||||
|
create or alter user mick_junior password 'jun' revoke admin role;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
recreate table test(id int, text varchar(30), changed_by_user varchar(31), changed_by_role varchar(31));
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
create trigger test_biu for test active before insert or update position 0 as
|
||||||
|
begin
|
||||||
|
new.changed_by_user = current_user;
|
||||||
|
new.changed_by_role = current_role;
|
||||||
|
end
|
||||||
|
^
|
||||||
|
set term ;^
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into test(id, text) values(1, 'Initial data, added by SYSDBA');
|
||||||
|
insert into test(id, text) values(2, 'Initial data, added by SYSDBA');
|
||||||
|
insert into test(id, text) values(3, 'Initial data, added by SYSDBA');
|
||||||
|
select * from test;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
grant select on test to public;
|
||||||
|
grant create role to john_senior;
|
||||||
|
grant update(text) on test to john_senior with grant option;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
--set echo on;
|
||||||
|
--show grants;
|
||||||
|
connect '$(DSN)' user 'JOHN_SENIOR' password 'sen';
|
||||||
|
create role modifier;
|
||||||
|
commit;
|
||||||
|
grant update (text) on test to modifier; -- this CAN be done by john_senior because he was granted to control access on this field
|
||||||
|
grant modifier to mick_junior; -- this CAN be done by john_senior because he CREATED role 'modifier' and thus he is MEMBER of it.
|
||||||
|
commit;
|
||||||
|
--show grants;
|
||||||
|
|
||||||
|
connect '$(DSN)' user 'MICK_JUNIOR' password 'jun' role 'MODIFIER';
|
||||||
|
select current_user, current_role from rdb$database;
|
||||||
|
update test set text = 'Update-1: through the ROLE' where id = 1;
|
||||||
|
select * from test;
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
connect '$(DSN)' user 'JOHN_SENIOR' password 'sen';
|
||||||
|
select current_user, current_role from rdb$database;
|
||||||
|
update test set text = 'Update-2: directly by USER' where id = 2;
|
||||||
|
select * from test;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
connect '$(DSN)' user 'JOHN_SENIOR' password 'sen';
|
||||||
|
|
||||||
|
-- ###########################################################################################
|
||||||
|
-- ### H e r e w e R E V O K E r i g h t t o u p d a t e c o l u m n ###
|
||||||
|
-- ###########################################################################################
|
||||||
|
-- ::: NB ::: See CORE-4836:
|
||||||
|
-- As of WI-T3.0.0.31873, if we want to revoke privilege on certain COLUMN update, we must do
|
||||||
|
-- it immediatelly after reconnect, NO issuing any DML here (like `select * from test` etc).
|
||||||
|
|
||||||
|
revoke update(text) on test from modifier; ------------- ########### R E V O K E ########
|
||||||
|
commit;
|
||||||
|
|
||||||
|
connect '$(DSN)' user 'MICK_JUNIOR' password 'jun' role 'MODIFIER';
|
||||||
|
select current_user, current_role from rdb$database;
|
||||||
|
update test set text = 'Update-3: again using ROLE' where id = 3;
|
||||||
|
select * from test;
|
||||||
|
|
||||||
|
commit;
|
||||||
|
|
||||||
|
connect '$(DSN)' user 'SYSDBA' password 'masterkey';
|
||||||
|
|
||||||
|
drop user john_senior;
|
||||||
|
drop user mick_junior;
|
||||||
|
drop role modifier;
|
||||||
|
drop table test;
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
ID 1
|
||||||
|
TEXT Initial data, added by SYSDBA
|
||||||
|
CHANGED_BY_USER SYSDBA
|
||||||
|
CHANGED_BY_ROLE NONE
|
||||||
|
ID 2
|
||||||
|
TEXT Initial data, added by SYSDBA
|
||||||
|
CHANGED_BY_USER SYSDBA
|
||||||
|
CHANGED_BY_ROLE NONE
|
||||||
|
ID 3
|
||||||
|
TEXT Initial data, added by SYSDBA
|
||||||
|
CHANGED_BY_USER SYSDBA
|
||||||
|
CHANGED_BY_ROLE NONE
|
||||||
|
|
||||||
|
|
||||||
|
USER MICK_JUNIOR
|
||||||
|
ROLE MODIFIER
|
||||||
|
ID 1
|
||||||
|
TEXT Update-1: through the ROLE
|
||||||
|
CHANGED_BY_USER MICK_JUNIOR
|
||||||
|
CHANGED_BY_ROLE MODIFIER
|
||||||
|
ID 2
|
||||||
|
TEXT Initial data, added by SYSDBA
|
||||||
|
CHANGED_BY_USER SYSDBA
|
||||||
|
CHANGED_BY_ROLE NONE
|
||||||
|
ID 3
|
||||||
|
TEXT Initial data, added by SYSDBA
|
||||||
|
CHANGED_BY_USER SYSDBA
|
||||||
|
CHANGED_BY_ROLE NONE
|
||||||
|
|
||||||
|
USER JOHN_SENIOR
|
||||||
|
ROLE NONE
|
||||||
|
ID 1
|
||||||
|
TEXT Update-1: through the ROLE
|
||||||
|
CHANGED_BY_USER MICK_JUNIOR
|
||||||
|
CHANGED_BY_ROLE MODIFIER
|
||||||
|
ID 2
|
||||||
|
TEXT Update-2: directly by USER
|
||||||
|
CHANGED_BY_USER JOHN_SENIOR
|
||||||
|
CHANGED_BY_ROLE NONE
|
||||||
|
ID 3
|
||||||
|
TEXT Initial data, added by SYSDBA
|
||||||
|
CHANGED_BY_USER SYSDBA
|
||||||
|
CHANGED_BY_ROLE NONE
|
||||||
|
|
||||||
|
USER MICK_JUNIOR
|
||||||
|
ROLE MODIFIER
|
||||||
|
ID 1
|
||||||
|
TEXT Update-1: through the ROLE
|
||||||
|
CHANGED_BY_USER MICK_JUNIOR
|
||||||
|
CHANGED_BY_ROLE MODIFIER
|
||||||
|
ID 2
|
||||||
|
TEXT Update-2: directly by USER
|
||||||
|
CHANGED_BY_USER JOHN_SENIOR
|
||||||
|
CHANGED_BY_ROLE NONE
|
||||||
|
ID 3
|
||||||
|
TEXT Initial data, added by SYSDBA
|
||||||
|
CHANGED_BY_USER SYSDBA
|
||||||
|
CHANGED_BY_ROLE NONE
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 28000
|
||||||
|
no permission for UPDATE access to TABLE TEST
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
60
tests/bugs/core_0886_test.py
Normal file
60
tests/bugs/core_0886_test.py
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0886
|
||||||
|
# title: SPs in views
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-886
|
||||||
|
# min_versions: ['2.5.0']
|
||||||
|
# versions: 2.5.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """set term !!;
|
||||||
|
create procedure MY_PROCEDURE (input1 INTEGER)
|
||||||
|
returns (output1 INTEGER)
|
||||||
|
as begin
|
||||||
|
output1 = input1+1;
|
||||||
|
suspend;
|
||||||
|
end !!
|
||||||
|
set term ;!!
|
||||||
|
commit;
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """create view a_view as
|
||||||
|
select * from MY_PROCEDURE(1);
|
||||||
|
commit;
|
||||||
|
show view a_view;
|
||||||
|
select *from a_view;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """Database: localhost:C:btest2 mpugs.core_0886.fdb, User: SYSDBA
|
||||||
|
SQL> CON> SQL> SQL> OUTPUT1 INTEGER Nullable
|
||||||
|
View Source:
|
||||||
|
==== ======
|
||||||
|
|
||||||
|
select * from MY_PROCEDURE(1)
|
||||||
|
SQL>
|
||||||
|
OUTPUT1
|
||||||
|
============
|
||||||
|
2
|
||||||
|
|
||||||
|
SQL> SQL>"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
42
tests/bugs/core_0888_test.py
Normal file
42
tests/bugs/core_0888_test.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0888
|
||||||
|
# title: DDL - object in use
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-888
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.0.1
|
||||||
|
# qmid: bugs.core_888
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.0.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """SET TERM ^ ;
|
||||||
|
CREATE PROCEDURE TestProc
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
EXIT;
|
||||||
|
END ^
|
||||||
|
SET TERM ; ^
|
||||||
|
|
||||||
|
EXECUTE PROCEDURE TestProc;
|
||||||
|
|
||||||
|
DROP PROCEDURE TestProc;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.0.1')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.execute()
|
||||||
|
|
44
tests/bugs/core_0896_test.py
Normal file
44
tests/bugs/core_0896_test.py
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0896
|
||||||
|
# title: SUBSTRING with NULL offset or length don't return NULL
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-896
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.1
|
||||||
|
# qmid: bugs.core_896
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.1
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """select substring('abc' from null) from rdb$database;
|
||||||
|
select substring('abc' from 2 for null) from rdb$database;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """SUBSTRING
|
||||||
|
=========
|
||||||
|
<null>
|
||||||
|
|
||||||
|
SUBSTRING
|
||||||
|
=========
|
||||||
|
<null>
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.1')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
142
tests/bugs/core_0899_test.py
Normal file
142
tests/bugs/core_0899_test.py
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0899
|
||||||
|
# title: Problems with explicit cursors in unwanted states
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-899
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.5.0
|
||||||
|
# qmid: bugs.core_899-250
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = [('line:\\s[0-9]+,', 'line: x'), ('col:\\s[0-9]+', 'col: y')]
|
||||||
|
|
||||||
|
init_script_1 = """create table T (ID integer, TXT varchar(30));
|
||||||
|
commit;
|
||||||
|
|
||||||
|
insert into T values (1,'Text description');
|
||||||
|
commit;
|
||||||
|
|
||||||
|
set term ^;
|
||||||
|
|
||||||
|
create procedure SP_OK returns (ID integer, TXT varchar(30))
|
||||||
|
as
|
||||||
|
declare C cursor for ( select ID, TXT from T );
|
||||||
|
begin
|
||||||
|
open C;
|
||||||
|
while (1 = 1) do
|
||||||
|
begin
|
||||||
|
fetch C into :ID, :TXT;
|
||||||
|
if (ROW_COUNT = 0) then
|
||||||
|
leave;
|
||||||
|
update T set TXT = 'OK' where current of C;
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
close C;
|
||||||
|
end ^
|
||||||
|
|
||||||
|
create procedure SP_CLOSED returns (ID integer, TXT varchar(30))
|
||||||
|
as
|
||||||
|
declare C cursor for ( select ID, TXT from T );
|
||||||
|
begin
|
||||||
|
open C;
|
||||||
|
while (1 = 1) do
|
||||||
|
begin
|
||||||
|
fetch C into :ID, :TXT;
|
||||||
|
if (ROW_COUNT = 0) then
|
||||||
|
leave;
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
close C;
|
||||||
|
update T set TXT = 'SP_CLOSED' where current of C;
|
||||||
|
end ^
|
||||||
|
|
||||||
|
create procedure SP_NOTOPEN returns (ID integer, TXT varchar(30))
|
||||||
|
as
|
||||||
|
declare C cursor for ( select ID, TXT from T );
|
||||||
|
begin
|
||||||
|
update T set TXT = 'SP_NOTOPEN' where current of C;
|
||||||
|
open C;
|
||||||
|
while (1 = 1) do
|
||||||
|
begin
|
||||||
|
fetch C into :ID, :TXT;
|
||||||
|
if (ROW_COUNT = 0) then
|
||||||
|
leave;
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
close C;
|
||||||
|
end ^
|
||||||
|
|
||||||
|
create procedure SP_FETCHED returns (ID integer, TXT varchar(30))
|
||||||
|
as
|
||||||
|
declare C cursor for ( select ID, TXT from T );
|
||||||
|
begin
|
||||||
|
open C;
|
||||||
|
while (1 = 1) do
|
||||||
|
begin
|
||||||
|
fetch C into :ID, :TXT;
|
||||||
|
if (ROW_COUNT = 0) then
|
||||||
|
leave;
|
||||||
|
suspend;
|
||||||
|
end
|
||||||
|
update T set TXT = 'SP_FETCHED' where current of C;
|
||||||
|
close C;
|
||||||
|
end ^
|
||||||
|
|
||||||
|
set term ; ^
|
||||||
|
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """select * from SP_OK;
|
||||||
|
select * from SP_CLOSED;
|
||||||
|
select * from SP_NOTOPEN;
|
||||||
|
select * from SP_FETCHED;
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
ID TXT
|
||||||
|
============ ==============================
|
||||||
|
1 Text description
|
||||||
|
|
||||||
|
|
||||||
|
ID TXT
|
||||||
|
============ ==============================
|
||||||
|
1 OK
|
||||||
|
|
||||||
|
ID TXT
|
||||||
|
============ ==============================
|
||||||
|
|
||||||
|
ID TXT
|
||||||
|
============ ==============================
|
||||||
|
1 OK
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """Statement failed, SQLSTATE = 22000
|
||||||
|
no current record for fetch operation
|
||||||
|
-At procedure 'SP_CLOSED' line: 14, col: 3
|
||||||
|
Statement failed, SQLSTATE = 22000
|
||||||
|
no current record for fetch operation
|
||||||
|
-At procedure 'SP_NOTOPEN' line: 5, col: 3
|
||||||
|
Statement failed, SQLSTATE = 22000
|
||||||
|
no current record for fetch operation
|
||||||
|
-At procedure 'SP_FETCHED' line: 13, col: 3
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
68
tests/bugs/core_0903_test.py
Normal file
68
tests/bugs/core_0903_test.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0903
|
||||||
|
# title: New value of column is accessable before update
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-903
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 2.5.0
|
||||||
|
# qmid: None
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 2.5.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """CREATE TABLE TEST (
|
||||||
|
T1 INTEGER,
|
||||||
|
T2 INTEGER,
|
||||||
|
T3 INTEGER,
|
||||||
|
T4 INTEGER
|
||||||
|
);
|
||||||
|
|
||||||
|
Insert into test (T1, T2, T3, T4) values ( 0, 0 , 0, 0);
|
||||||
|
|
||||||
|
SET TERM ^ ;
|
||||||
|
|
||||||
|
CREATE OR ALTER PROCEDURE CH_TEST (
|
||||||
|
num integer)
|
||||||
|
as
|
||||||
|
begin
|
||||||
|
|
||||||
|
update TEST
|
||||||
|
set
|
||||||
|
T1= T1 + T2 + T3 + T4 + :NUM
|
||||||
|
,T2= T1 + T2 + T3 + T4 + :NUM
|
||||||
|
,T3= T1 + T2 + T3 + T4 + :NUM
|
||||||
|
,T4= T1 + T2 + T3 + T4 + :NUM
|
||||||
|
;
|
||||||
|
|
||||||
|
end^
|
||||||
|
|
||||||
|
SET TERM ; ^
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """execute procedure ch_test( 1 );
|
||||||
|
select * from test;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
T1 T2 T3 T4
|
||||||
|
============ ============ ============ ============
|
||||||
|
1 1 1 1
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=2.5.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
87
tests/bugs/core_0907_test.py
Normal file
87
tests/bugs/core_0907_test.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#coding:utf-8
|
||||||
|
#
|
||||||
|
# id: bugs.core_0907
|
||||||
|
# title: Server crash on violation of NOT NULL constraint
|
||||||
|
# decription:
|
||||||
|
# tracker_id: CORE-907
|
||||||
|
# min_versions: []
|
||||||
|
# versions: 3.0
|
||||||
|
# qmid: bugs.core_907-250
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from firebird.qa import db_factory, isql_act, Action
|
||||||
|
|
||||||
|
# version: 3.0
|
||||||
|
# resources: None
|
||||||
|
|
||||||
|
substitutions_1 = []
|
||||||
|
|
||||||
|
init_script_1 = """
|
||||||
|
recreate table crash (a1 integer,a2 integer,a3 integer, a4 integer) ;
|
||||||
|
commit;
|
||||||
|
insert into crash (a1, a2, a3, a4) values ( 1, 2, 3, 4);
|
||||||
|
insert into crash (a1, a2, a3 ) values ( 2, 3, 4 );
|
||||||
|
insert into crash (a1, a2, a4) values ( 2, 3, 4);
|
||||||
|
commit;
|
||||||
|
alter table crash add a5 computed by (a2*a3*a4);
|
||||||
|
commit;
|
||||||
|
"""
|
||||||
|
|
||||||
|
db_1 = db_factory(sql_dialect=3, init=init_script_1)
|
||||||
|
|
||||||
|
test_script_1 = """
|
||||||
|
-- Since 3.0 one may do like this (and NOT by updating RDB tables):
|
||||||
|
-- ALTER TABLE <table name> ALTER <field name> [NOT] NULL
|
||||||
|
-- ALTER DOMAIN <domain name> [NOT] NULL
|
||||||
|
-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
-- 02.04.2015: since rev. 61204 (build 3.0.0.31767)syntax of altering nullability for
|
||||||
|
-- domains and tables has been changed: mandatory SET | DROP clause now needed, i.e.:
|
||||||
|
-- ALTER TABLE <table name> ALTER <field name> {DROP | SET} NOT NULL
|
||||||
|
-- ALTER DOMAIN <domain name> {DROP | SET} NOT NULL
|
||||||
|
-- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||||
|
|
||||||
|
-- This attempt will FAIL with message:
|
||||||
|
-- -Cannot make field A5 of table CRASH NOT NULL because there are NULLs present
|
||||||
|
alter table crash alter a5 SET not null;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
update crash set a3=1 where a3 is null;
|
||||||
|
update crash set a4=1 where a4 is null;
|
||||||
|
commit;
|
||||||
|
|
||||||
|
alter table crash alter a1 SET not null;
|
||||||
|
alter table crash alter a2 SET not null;
|
||||||
|
alter table crash alter a3 SET not null;
|
||||||
|
alter table crash alter a4 SET not null;
|
||||||
|
alter table crash alter a5 SET not null;
|
||||||
|
commit;
|
||||||
|
update crash set a1=null, a2=null, a3=null,a4=null rows 1;
|
||||||
|
commit;
|
||||||
|
show table crash;
|
||||||
|
"""
|
||||||
|
|
||||||
|
act_1 = isql_act('db_1', test_script_1, substitutions=substitutions_1)
|
||||||
|
|
||||||
|
expected_stdout_1 = """
|
||||||
|
A1 INTEGER Not Null
|
||||||
|
A2 INTEGER Not Null
|
||||||
|
A3 INTEGER Not Null
|
||||||
|
A4 INTEGER Not Null
|
||||||
|
A5 Computed by: (a2*a3*a4)
|
||||||
|
"""
|
||||||
|
expected_stderr_1 = """
|
||||||
|
Statement failed, SQLSTATE = 22006
|
||||||
|
unsuccessful metadata update
|
||||||
|
-Cannot make field A5 of table CRASH NOT NULL because there are NULLs present
|
||||||
|
Statement failed, SQLSTATE = 23000
|
||||||
|
validation error for column "CRASH"."A1", value "*** null ***"
|
||||||
|
"""
|
||||||
|
|
||||||
|
@pytest.mark.version('>=3.0')
|
||||||
|
def test_1(act_1: Action):
|
||||||
|
act_1.expected_stdout = expected_stdout_1
|
||||||
|
act_1.expected_stderr = expected_stderr_1
|
||||||
|
act_1.execute()
|
||||||
|
assert act_1.clean_expected_stderr == act_1.clean_stderr
|
||||||
|
assert act_1.clean_expected_stdout == act_1.clean_stdout
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user