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

308 lines
10 KiB
Python
Raw Normal View History

2021-04-26 20:07:00 +02:00
#coding:utf-8
#
# id: bugs.core_4470
# title: gbak fails to restore database containing dependency between views and packaged functions
2021-11-26 19:20:43 +01:00
# decription:
2021-04-26 20:07:00 +02:00
# Confirmed on WI-T3.0.0.30809 Firebird 3.0 Alpha 2:
# gbak: ERROR:action cancelled by trigger (0) to preserve data integrity
# gbak: ERROR: could not find object for GRANT
# gbak:Exiting before completion due to errors
# ============================================
# 28.10.2019:
# 1. Replaced PSQL function name 'localtime()' with 'fn_local_time()': first of them became keyword in FB 4.0
# 2.Checked on:
# 4.0.0.1635 SS: 3.384s.
# 4.0.0.1633 CS: 3.438s.
# 3.0.5.33180 SS: 2.137s.
# 3.0.5.33178 CS: 2.490s.
2021-11-26 19:20:43 +01:00
#
2021-04-26 20:07:00 +02:00
# tracker_id: CORE-4470
# min_versions: ['3.0']
# versions: 3.0
# qmid: None
import pytest
2021-11-26 19:20:43 +01:00
from pathlib import Path
from firebird.qa import db_factory, python_act, Action, temp_file
from firebird.driver import SrvRestoreFlag
2021-04-26 20:07:00 +02:00
# version: 3.0
# resources: None
substitutions_1 = []
init_script_1 = """
set bail on;
set autoddl on;
create domain dbigint as bigint;
create domain dblob as blob sub_type 0 segment size 80;
create domain did as bigint not null;
create domain dinteger as integer;
create domain dn31 as numeric(3, 1);
create domain dn41 as numeric(4, 1);
create domain dn51 as numeric(5, 1);
create domain dreal as double precision;
create domain dsmallint as smallint;
create domain dtime as timestamp;
create domain dvc255 as varchar(255);
create domain dvc512 as varchar(512);
commit;
set autoddl off;
set term ^;
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
create package wf as
begin
function cest (t dtime) returns dtime;
function cet (t dtime) returns dtime;
function fn_local_time (t dtime) returns dtime;
function dewpoint (temp dreal, hum dsmallint) returns dreal;
function yesterday returns dtime;
function altitude returns dreal;
function current_xml returns dvc512;
function relpressure(airpressureabsolute dreal,temperature dreal,altitude dreal, humidity dreal) returns dreal;
end^
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
set term ;^
commit work;
set autoddl on;
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
create table constants (id did generated by default as identity not null,
typ dvc255,
val dvc255,
keys dbigint,
primary key (id));
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
create table raw (id did generated by default as identity not null,
readtime dtime not null,
delay dsmallint,
hum_in dsmallint,
temp_in dreal,
hum_out dsmallint,
temp_out dreal,
abs_pressure dreal,
wind_ave dreal,
wind_gust dreal,
wind_dir dsmallint,
rain dreal,
status dsmallint,
illuminance dreal,
uv dsmallint,
primary key (id),
constraint unq1_raw unique (readtime));
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
create table timezone (jahr dsmallint not null,
gmt_from dtime,
gmt_thru dtime,
constraint pk_timezone primary key (jahr));
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
create index raw_idx1 on raw (hum_in);
create descending index raw_idx10 on raw (abs_pressure);
create descending index raw_idx11 on raw (readtime);
create descending index raw_idx12 on raw (rain);
create index raw_idx2 on raw (temp_in);
create index raw_idx3 on raw (hum_out);
create index raw_idx4 on raw (temp_out);
create index raw_idx5 on raw (abs_pressure);
create index raw_idx6 on raw (wind_ave);
create index raw_idx7 on raw (wind_gust);
create index raw_idx8 on raw (wind_dir);
create index raw_idx9 on raw (rain);
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
create view meteo (timestamp_utc, timestamp_local, tempint, humint, temp, hum, wind, wind_dir, wind_gust, wind_gust_dir, dew_point, rain, rain_rate, pressure, uv_index, solar_rad) as
select readtime, wf.fn_local_time(readtime), temp_in, hum_in, temp_out, hum_out, wind_ave / 3.6 , 22.5 * wind_dir, wind_gust / 3.6 ,
22.5 * wind_dir, wf.dewpoint(temp_out, hum_out), cast(rain - lead(rain) over(order by readtime desc) as numeric (6,3)) , 0,
2.8+wf.relpressure(abs_pressure, temp_out, wf.altitude(), hum_out), 0, 0
from raw;
commit;
set autoddl off;
set term ^;
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
create package body wf as
begin
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
function CEST (T dtime)returns dtime
AS
begin
return dateadd (2 hour to t);
end
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
function CET (T dtime)returns dtime
AS
begin
return dateadd (1 hour to t);
end
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
function altitude returns dreal
as
begin
return (select c.val from constants c where c.typ='Altitude');
end
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
function fn_local_time (t dtime)returns dtime
as
declare variable jahr dsmallint;
declare variable gmt_from dtime;
declare variable gmt_thru dtime;
begin
select tz.gmt_from, tz.gmt_thru
from timezone tz where tz.jahr=extract(year from :t)
into :gmt_from, :gmt_thru;
if (t between :gmt_from and :gmt_thru) then
begin
return dateadd (2 hour to t);
end
else
return dateadd (1 hour to t);
end
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
function relpressure (airpressureabsolute dreal, temperature dreal, altitude dreal, humidity dreal) returns dreal
as
declare variable g_n dreal;
declare variable gam dreal;
declare variable r dreal;
declare variable m dreal;
declare variable r_0 dreal;
declare variable t_0 dreal;
declare variable c dreal;
declare variable e_0 dreal;
declare variable f_rel dreal;
declare variable e_d dreal;
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
begin
g_n = 9.80665;-- erdbeschleunigung (m/s^2)
gam = 0.0065;--temperaturabnahme in k pro geopotentiellen metern (k/gpm)
r = 287.06;--gaskonstante fur trockene luft (r = r_0 / m)
m = 0.0289644;--molare masse trockener luft (j/kgk)
r_0 = 8.314472;--allgemeine gaskonstante (j/molk)
t_0 = 273.15;--umrechnung von c in k
c = 0.11;--dwd-beiwert fur die berucksichtigung der luftfeuchte
e_0 = 6.11213;-- (hpa)
f_rel = humidity / 100;--relative luftfeuchte (0-1.0)
e_d = f_rel * e_0 * exp((17.5043 * temperature) / (241.2 + temperature));--momentaner stationsdampfdruck (hpa)
return airpressureabsolute * exp((g_n * altitude) / (r * (temperature + t_0 + c * e_d + ((gam * altitude) / 2))));
end
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
function yesterday returns dtime
as
begin
return dateadd (-1 day to current_date);
end
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
function dewpoint (temp dreal, hum dsmallint)
returns dreal
as
declare variable gamma dreal;
declare variable a dreal;
declare variable b dreal;
begin
if ((coalesce(temp,0)=0) or (coalesce(hum,0)=0)) then
return 0;
else
begin
return temp - ((100 - hum) / 5.0);
end
end
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
function current_xml returns dvc512
as
declare variable timestamp_utc type of column meteo.timestamp_utc;
declare variable timestamp_local type of column meteo.timestamp_local;
declare variable tempint type of column meteo.tempint;
declare variable humint type of column meteo.humint;
declare variable temp type of column meteo.temp;
declare variable hum type of column meteo.hum;
declare variable wind type of column meteo.wind;
declare variable wind_dir type of column meteo.wind_dir;
declare variable wind_gust type of column meteo.wind_gust;
declare variable wind_gust_dir type of column meteo.wind_gust_dir;
declare variable dew_point type of column meteo.dew_point;
declare variable rain type of column meteo.rain;
declare variable rain_rate type of column meteo.rain_rate;
declare variable pressure type of column meteo.pressure;
declare variable uv_index type of column meteo.uv_index;
declare variable solar_rad type of column meteo.solar_rad;
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
begin
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
select first 1 timestamp_utc,timestamp_local, tempint, humint, temp, hum, wind, wind_dir, wind_gust, wind_gust_dir, dew_point,
rain, rain_rate, pressure, uv_index, solar_rad
from meteo order by timestamp_utc desc
into :timestamp_utc, :timestamp_local, :tempint, :humint, :temp, :hum, :wind, :wind_dir, :wind_gust, :wind_gust_dir,
:dew_point, :rain, :rain_rate, :pressure, :uv_index, :solar_rad;
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
return '<current><thInt><temp>'||
tempint||
'</temp><humidity>'||
humint||
'</humidity></thInt><th1><temp>'||
temp||
'</temp><humidity>'||
hum||
'</humidity></th1><rain><rate>'||
rain_rate||
'</rate></rain><wind><avgSpeed>'||
wind||
'</avgSpeed><dirDeg>'||
wind_dir||
'</dirDeg><gustSpeed>'||
wind_gust||
'</gustSpeed></wind><barometer><pressure>'||
pressure||
'</pressure></barometer><time>'||
substring (timestamp_local from 1 for 19)||
'</time></current>';
end
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
end^
2021-11-26 19:20:43 +01:00
2021-04-26 20:07:00 +02:00
set term ;^
2021-11-26 19:20:43 +01:00
commit;
"""
2021-04-26 20:07:00 +02:00
db_1 = db_factory(page_size=4096, sql_dialect=3, init=init_script_1)
# test_script_1
#---
# import os
2021-11-26 19:20:43 +01:00
#
2021-04-26 20:07:00 +02:00
# fbk = os.path.join(context['temp_directory'],'core_4470-backup.fbk')
# fbn = os.path.join(context['temp_directory'],'core_4470-restored.fdb')
# print('Creating backup...')
# runProgram('gbak',['-b','-user',user_name,'-password',user_password,dsn,fbk])
# print('Creating restore...')
# runProgram('gbak',['-rep','-user',user_name,'-password',user_password,fbk,fbn])
# script = '''show view; show package;'''
# runProgram('isql',[fbn,'-q','-user',user_name,'-password',user_password],script)
# if os.path.isfile(fbk):
# os.remove(fbk)
# if os.path.isfile(fbn):
# os.remove(fbn)
2021-11-26 19:20:43 +01:00
#
2021-04-26 20:07:00 +02:00
#---
2021-11-26 19:20:43 +01:00
act_1 = python_act('db_1', substitutions=substitutions_1)
2021-04-26 20:07:00 +02:00
expected_stdout_1 = """
METEO
WF
2021-11-26 19:20:43 +01:00
"""
2021-04-26 20:07:00 +02:00
2021-11-26 19:20:43 +01:00
fbk_file_1 = temp_file('test.fbk')
2021-04-26 20:07:00 +02:00
2021-11-26 19:20:43 +01:00
@pytest.mark.version('>=3.0')
def test_1(act_1: Action, fbk_file_1: Path):
with act_1.connect_server() as srv:
srv.database.backup(database=act_1.db.db_path, backup=fbk_file_1)
2021-11-26 19:20:43 +01:00
srv.wait()
srv.database.restore(backup=fbk_file_1, database=act_1.db.db_path,
2021-11-26 19:20:43 +01:00
flags=SrvRestoreFlag.REPLACE)
srv.wait()
act_1.expected_stdout = expected_stdout_1
act_1.isql(switches=['-q'], input='show view; show package;')
assert act_1.clean_stdout == act_1.clean_expected_stdout