6
0
mirror of https://github.com/FirebirdSQL/firebird-qa.git synced 2025-01-22 13:33:07 +01:00

Firebird engine tests

This commit is contained in:
Pavel Císař 2021-04-26 20:07:00 +02:00
parent 1445115e0e
commit 7a9962e6bf
2243 changed files with 378541 additions and 0 deletions

1
tests/__init__.py Normal file
View File

@ -0,0 +1 @@
# Python module

1
tests/bugs/__init__.py Normal file
View File

@ -0,0 +1 @@
# Python module

View 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_core_0000_1(act_1: Action):
act_1.execute()

View 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_core_0001_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View 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_core_0002_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0010_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0014_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0037_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/test_core_0039.py Normal file

File diff suppressed because it is too large Load Diff

View 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_core_0053_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0058_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View 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_core_0059_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View 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_core_0063_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0070_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0076_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0085_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -0,0 +1,45 @@
#coding:utf-8
#
# id: bugs.core_86
# 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_core_86_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0088_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0089_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -0,0 +1,50 @@
#coding:utf-8
#
# id: bugs.core_91
# 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_core_91_1(act_1: Action):
act_1.execute()

View File

@ -0,0 +1,53 @@
#coding:utf-8
#
# id: bugs.core_99
# 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_core_99_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0101_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0104_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View 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_core_0115_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0116_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View 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_core_0117_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0119_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

View 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_core_0142_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0143_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0148_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0149_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0165_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0166_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0185_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

View 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_core_0188_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0190_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

View 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_core_0195_1(act_1: Action):
act_1.execute()

View 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_core_0198_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0200_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0203_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0209_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

View 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_core_0210_1(db_1):
pytest.fail("Test not IMPLEMENTED")

View 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_core_0211_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0214_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0216_1(db_1):
pytest.fail("Test not IMPLEMENTED")

View 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_core_0223_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

View 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_core_0282_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

View 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_core_0284_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0297_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0304_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_core_0304_2(act_2: Action):
act_2.expected_stderr = expected_stderr_2
act_2.execute()
assert act_2.clean_expected_stderr == act_2.clean_stderr

View 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_core_0335_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

View 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_core_0337_1(db_1):
pytest.fail("Test not IMPLEMENTED")

View 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_core_0366_1(act_1: Action):
act_1.execute()

View 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_core_0389_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0405_1(db_1):
pytest.fail("Test not IMPLEMENTED")

View 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&amp;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_core_0461_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0474_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0475_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0479_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_core_0479_2(act_2: Action):
act_2.expected_stdout = expected_stdout_2
act_2.execute()
assert act_2.clean_expected_stdout == act_2.clean_stdout

View 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_core_0480_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/test_core_0501.py Normal file

File diff suppressed because it is too large Load Diff

View 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_core_0507_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View 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_core_0521_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

View 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_core_0583_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

View 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_core_0606_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

View 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_core_0610_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0611_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0623_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0625_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0629_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -0,0 +1,45 @@
#coding:utf-8
#
# id: bugs.core_655
# 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_core_655_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0696_1(act_1: Action):
act_1.execute()

View 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_core_0733_1(db_1):
pytest.fail("Test not IMPLEMENTED")

View 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_core_0769_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0790_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0800_1(db_1):
pytest.fail("Test not IMPLEMENTED")

View File

@ -0,0 +1,172 @@
#coding:utf-8
#
# id: bugs.core_805
# 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_core_805_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0824_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -0,0 +1,49 @@
#coding:utf-8
#
# id: bugs.core_842
# 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_core_842_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0847_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

View 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_core_0850_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View 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_core_0851_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View File

@ -0,0 +1,40 @@
#coding:utf-8
#
# id: bugs.core_852
# 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_core_852_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0855_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View 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_core_0856_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -0,0 +1,94 @@
#coding:utf-8
#
# id: bugs.core_857
# 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_core_857_1(db_1):
pytest.fail("Test not IMPLEMENTED")

View File

@ -0,0 +1,107 @@
#coding:utf-8
#
# id: bugs.core_858
# 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_core_858_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_core_858_2(act_2: Action):
act_2.execute()

View 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_core_0859_1(db_1):
pytest.fail("Test not IMPLEMENTED")

View File

@ -0,0 +1,53 @@
#coding:utf-8
#
# id: bugs.core_866
# 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_core_866_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View 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_core_0870_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -0,0 +1,50 @@
#coding:utf-8
#
# id: bugs.core_871
# 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_core_871_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -0,0 +1,74 @@
#coding:utf-8
#
# id: bugs.core_878
# 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_core_878_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -0,0 +1,46 @@
#coding:utf-8
#
# id: bugs.core_879
# 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_core_879_1(act_1: Action):
act_1.expected_stderr = expected_stderr_1
act_1.execute()
assert act_1.clean_expected_stderr == act_1.clean_stderr

View File

@ -0,0 +1,49 @@
#coding:utf-8
#
# id: bugs.core_881
# 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_core_881_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

View File

@ -0,0 +1,141 @@
#coding:utf-8
#
# id: bugs.core_883
# 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_core_883_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View 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_core_0885_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

View 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_core_0886_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -0,0 +1,42 @@
#coding:utf-8
#
# id: bugs.core_888
# 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_core_888_1(act_1: Action):
act_1.execute()

View File

@ -0,0 +1,44 @@
#coding:utf-8
#
# id: bugs.core_896
# 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_core_896_1(act_1: Action):
act_1.expected_stdout = expected_stdout_1
act_1.execute()
assert act_1.clean_expected_stdout == act_1.clean_stdout

View File

@ -0,0 +1,142 @@
#coding:utf-8
#
# id: bugs.core_899
# 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_core_899_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