2021-04-26 20:07:00 +02:00
|
|
|
#coding:utf-8
|
|
|
|
|
2022-01-25 22:55:48 +01:00
|
|
|
"""
|
|
|
|
ID: issue-5864
|
|
|
|
ISSUE: 5864
|
2022-02-02 15:46:19 +01:00
|
|
|
TITLE: Error "block size exceeds implementation restriction" while inner joining large
|
|
|
|
datasets with a long key using the HASH JOIN plan
|
2022-01-25 22:55:48 +01:00
|
|
|
DESCRIPTION:
|
|
|
|
Hash join have to operate with keys of total length >= 1 Gb if we want to reproduce runtime error
|
|
|
|
"Statement failed, SQLSTATE = HY001 / unable to allocate memory from operating system"
|
|
|
|
If test table that serves as the source for HJ has record length about 65 Kb than not less than 16K records must be added there.
|
|
|
|
If we use charset UTF8 than record length in bytes will be 8 times of declared field_len, so we declare field with len = 8191 charactyer
|
|
|
|
(and this is current implementation limit).
|
|
|
|
Than we add into this table >= 16Kb rows of unicode (NON-ascii!) characters.
|
|
|
|
Finally, we launch query against this table and this query will use hash join because of missed indices.
|
|
|
|
We have to check that NO errors occured during this query.
|
2021-04-26 20:07:00 +02:00
|
|
|
|
2022-04-07 20:16:14 +02:00
|
|
|
Discussed with dimitr: letters 08-jan-2018 .. 06-feb-2018.
|
2022-01-25 22:55:48 +01:00
|
|
|
JIRA: CORE-5598
|
2022-02-02 15:46:19 +01:00
|
|
|
FBTEST: bugs.core_5598
|
2022-04-07 20:16:14 +02:00
|
|
|
NOTES:
|
|
|
|
[07.04.2022] pzotov
|
|
|
|
FB 5.0.0.455 and later: data sources with equal cardinality now present in the HASH plan in order they are specified in the query.
|
|
|
|
Reversed order was used before this build. Because of this, two cases of expected stdout must be taken in account, see variables
|
|
|
|
'fb3x_checked_stdout' and 'fb5x_checked_stdout'.
|
2022-01-25 22:55:48 +01:00
|
|
|
"""
|
2021-04-26 20:07:00 +02:00
|
|
|
|
2022-01-25 22:55:48 +01:00
|
|
|
import pytest
|
|
|
|
from firebird.qa import *
|
2021-04-26 20:07:00 +02:00
|
|
|
|
2022-01-25 22:55:48 +01:00
|
|
|
substitutions = [('[ \t]+', ' '), ('.*RECORD LENGTH:[ \t]+[\\d]+[ \t]*\\)', ''),
|
|
|
|
('.*COUNT[ \t]+[\\d]+', ''), ('(?m)DATABASE:.*\\n?', '')]
|
2021-04-26 20:07:00 +02:00
|
|
|
|
2022-01-25 22:55:48 +01:00
|
|
|
db = db_factory(charset='UTF8')
|
2021-12-09 19:26:42 +01:00
|
|
|
|
2022-01-25 22:55:48 +01:00
|
|
|
act = python_act('db', substitutions=substitutions)
|
2021-04-26 20:07:00 +02:00
|
|
|
|
2022-04-07 20:16:14 +02:00
|
|
|
fb3x_checked_stdout = """
|
|
|
|
PLAN HASH (B NATURAL, A NATURAL)
|
|
|
|
"""
|
|
|
|
|
|
|
|
fb5x_checked_stdout = """
|
|
|
|
PLAN HASH (A NATURAL, B NATURAL)
|
2021-12-09 19:26:42 +01:00
|
|
|
"""
|
2021-04-26 20:07:00 +02:00
|
|
|
|
2021-12-09 19:26:42 +01:00
|
|
|
MIN_RECS_TO_ADD = 17000
|
2021-04-26 20:07:00 +02:00
|
|
|
|
2022-01-25 22:55:48 +01:00
|
|
|
test_script = """
|
2022-04-07 20:16:14 +02:00
|
|
|
set list on;
|
|
|
|
set plan on;
|
2021-12-09 19:26:42 +01:00
|
|
|
select count(*) from test a join test b using(id, s);
|
|
|
|
quit;
|
|
|
|
"""
|
2021-04-26 20:07:00 +02:00
|
|
|
|
2021-12-09 19:26:42 +01:00
|
|
|
@pytest.mark.version('>=3.0.3')
|
2022-01-25 22:55:48 +01:00
|
|
|
def test_1(act: Action):
|
|
|
|
with act.db.connect(charset='utf8') as con:
|
2021-12-09 19:26:42 +01:00
|
|
|
con.execute_immediate('create table test(id int, s varchar(8191))')
|
|
|
|
con.commit()
|
|
|
|
c = con.cursor()
|
|
|
|
c.execute(f"insert into test(id, s) select row_number()over(), lpad('', 8191, 'Алексей, Łukasz, Máté, François, Jørgen, Νικόλαος') from rdb$types,rdb$types rows {MIN_RECS_TO_ADD}")
|
|
|
|
con.commit()
|
2022-04-07 20:16:14 +02:00
|
|
|
|
2022-04-08 13:16:01 +02:00
|
|
|
act.expected_stdout = fb3x_checked_stdout if act.is_version('<5') else fb5x_checked_stdout
|
2022-01-25 22:55:48 +01:00
|
|
|
act.isql(switches=['-q'], input=test_script)
|
|
|
|
act.stdout = act.stdout.upper()
|
|
|
|
assert act.clean_stdout == act.clean_expected_stdout
|