mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 19:37:16 +02:00
Add direct join support for Spider
Includes Spider patches - 062_mariadb-10.2.0.direct_join_1and3.diff - 063_mariadb-10.2.0.direct_join_for_single_partition.diff - Test cases from Kentoku Allows Spider to push full joins to the Spider engine trough the create_group_by interface. Other things: - Increased MYSQL_VERSION_ID to check for 10211 (latest 10.2 version) - Fix for const_table at calling create_group_by(). Original author: Kentoku SHIBA
This commit is contained in:
parent
bfaf2d6e35
commit
52ca07c2a0
15 changed files with 851 additions and 14 deletions
|
|
@ -9398,9 +9398,6 @@ ulonglong ha_spider::table_flags() const
|
|||
#ifdef SPIDER_ENGINE_CONDITION_PUSHDOWN_IS_ALWAYS_ON
|
||||
HA_CAN_TABLE_CONDITION_PUSHDOWN |
|
||||
#endif
|
||||
#ifdef HA_SKIP_OPTIMIZE_CONST_TABLE
|
||||
HA_SKIP_OPTIMIZE_CONST_TABLE |
|
||||
#endif
|
||||
#ifdef HA_CAN_BULK_ACCESS
|
||||
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
|
||||
(support_bulk_access_hs() ? HA_CAN_BULK_ACCESS : 0) |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
--let $OUTPUT_CHILD_GROUP2= $OUTPUT_CHILD_GROUP2_BACKUP
|
||||
--let $USE_GENERAL_LOG= $USE_GENERAL_LOG_BACKUP
|
||||
--disable_warnings
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--source ../t/test_deinit.inc
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
--enable_warnings
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
--disable_warnings
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--source ../t/test_init.inc
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
--enable_warnings
|
||||
let $CHILD2_1_SELECT_ARGUMENT1=
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
|
||||
--let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2
|
||||
--let $OUTPUT_CHILD_GROUP2= 1
|
||||
--let $USE_GENERAL_LOG_BACKUP= $USE_GENERAL_LOG
|
||||
--let $USE_GENERAL_LOG= 1
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
--connection master_1
|
||||
--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP
|
||||
--let $MASTER_1_COMMENT_2_2= $MASTER_1_COMMENT_2_2_BACKUP
|
||||
--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP
|
||||
--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP
|
||||
--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP
|
||||
--let $CHILD2_1_DROP_TABLES2= $CHILD2_1_DROP_TABLES2_BACKUP
|
||||
--let $CHILD2_1_CREATE_TABLES2= $CHILD2_1_CREATE_TABLES2_BACKUP
|
||||
--let $CHILD2_1_SELECT_TABLES2= $CHILD2_1_SELECT_TABLES2_BACKUP
|
||||
--let $CHILD2_2_DROP_TABLES= $CHILD2_2_DROP_TABLES_BACKUP
|
||||
--let $CHILD2_2_CREATE_TABLES= $CHILD2_2_CREATE_TABLES_BACKUP
|
||||
--let $CHILD2_2_SELECT_TABLES= $CHILD2_2_SELECT_TABLES_BACKUP
|
||||
--let $CHILD2_2_DROP_TABLES2= $CHILD2_2_DROP_TABLES2_BACKUP
|
||||
--let $CHILD2_2_CREATE_TABLES2= $CHILD2_2_CREATE_TABLES2_BACKUP
|
||||
--let $CHILD2_2_SELECT_TABLES2= $CHILD2_2_SELECT_TABLES2_BACKUP
|
||||
--let $CHILD2_3_DROP_TABLES= $CHILD2_3_DROP_TABLES_BACKUP
|
||||
--let $CHILD2_3_CREATE_TABLES= $CHILD2_3_CREATE_TABLES_BACKUP
|
||||
--let $CHILD2_3_SELECT_TABLES= $CHILD2_3_SELECT_TABLES_BACKUP
|
||||
--let $CHILD2_3_DROP_TABLES2= $CHILD2_3_DROP_TABLES2_BACKUP
|
||||
--let $CHILD2_3_CREATE_TABLES2= $CHILD2_3_CREATE_TABLES2_BACKUP
|
||||
--let $CHILD2_3_SELECT_TABLES2= $CHILD2_3_SELECT_TABLES2_BACKUP
|
||||
--let $OUTPUT_CHILD_GROUP2= $OUTPUT_CHILD_GROUP2_BACKUP
|
||||
--let $USE_GENERAL_LOG= $USE_GENERAL_LOG_BACKUP
|
||||
--disable_warnings
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--source ../t/test_deinit.inc
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
--enable_warnings
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
--disable_warnings
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--source ../t/test_init.inc
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
--enable_warnings
|
||||
--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1
|
||||
let $MASTER_1_COMMENT_2_1=
|
||||
COMMENT='table "tbl_a"'
|
||||
PARTITION BY RANGE(value) (
|
||||
PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1"',
|
||||
PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_2"',
|
||||
PARTITION pt3 VALUES LESS THAN (15) COMMENT='srv "s_2_3"'
|
||||
);
|
||||
--let $MASTER_1_COMMENT_2_2_BACKUP= $MASTER_1_COMMENT_2_2
|
||||
let $MASTER_1_COMMENT_2_2=
|
||||
COMMENT='table "tbl_b"'
|
||||
PARTITION BY RANGE(value2) (
|
||||
PARTITION pt1 VALUES LESS THAN (5) COMMENT='srv "s_2_1"',
|
||||
PARTITION pt2 VALUES LESS THAN (10) COMMENT='srv "s_2_2"',
|
||||
PARTITION pt3 VALUES LESS THAN (15) COMMENT='srv "s_2_3"'
|
||||
);
|
||||
--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES
|
||||
let $CHILD2_1_DROP_TABLES=
|
||||
DROP TABLE IF EXISTS tbl_a;
|
||||
--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES
|
||||
let $CHILD2_1_CREATE_TABLES=
|
||||
CREATE TABLE tbl_a (
|
||||
value int NOT NULL,
|
||||
PRIMARY KEY(value)
|
||||
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
|
||||
--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES
|
||||
let $CHILD2_1_SELECT_TABLES=
|
||||
SELECT value FROM tbl_a ORDER BY value;
|
||||
--let $CHILD2_1_DROP_TABLES2_BACKUP= $CHILD2_1_DROP_TABLES2
|
||||
let $CHILD2_1_DROP_TABLES2=
|
||||
DROP TABLE IF EXISTS tbl_b;
|
||||
--let $CHILD2_1_CREATE_TABLES2_BACKUP= $CHILD2_1_CREATE_TABLES2
|
||||
let $CHILD2_1_CREATE_TABLES2=
|
||||
CREATE TABLE tbl_b (
|
||||
value2 int NOT NULL,
|
||||
PRIMARY KEY(value2)
|
||||
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
|
||||
--let $CHILD2_1_SELECT_TABLES2_BACKUP= $CHILD2_1_SELECT_TABLES2
|
||||
let $CHILD2_1_SELECT_TABLES2=
|
||||
SELECT value FROM tbl_b ORDER BY value2;
|
||||
let $CHILD2_1_SELECT_ARGUMENT1=
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
|
||||
--let $CHILD2_2_DROP_TABLES_BACKUP= $CHILD2_2_DROP_TABLES
|
||||
let $CHILD2_2_DROP_TABLES=
|
||||
DROP TABLE IF EXISTS tbl_a;
|
||||
--let $CHILD2_2_CREATE_TABLES_BACKUP= $CHILD2_2_CREATE_TABLES
|
||||
let $CHILD2_2_CREATE_TABLES=
|
||||
CREATE TABLE tbl_a (
|
||||
value int NOT NULL,
|
||||
PRIMARY KEY(value)
|
||||
) $CHILD2_2_ENGINE $CHILD2_2_CHARSET;
|
||||
--let $CHILD2_2_SELECT_TABLES_BACKUP= $CHILD2_2_SELECT_TABLES
|
||||
let $CHILD2_2_SELECT_TABLES=
|
||||
SELECT value FROM tbl_a ORDER BY value;
|
||||
--let $CHILD2_2_DROP_TABLES2_BACKUP= $CHILD2_2_DROP_TABLES2
|
||||
let $CHILD2_2_DROP_TABLES2=
|
||||
DROP TABLE IF EXISTS tbl_b;
|
||||
--let $CHILD2_2_CREATE_TABLES2_BACKUP= $CHILD2_2_CREATE_TABLES2
|
||||
let $CHILD2_2_CREATE_TABLES2=
|
||||
CREATE TABLE tbl_b (
|
||||
value2 int NOT NULL,
|
||||
PRIMARY KEY(value2)
|
||||
) $CHILD2_2_ENGINE $CHILD2_2_CHARSET;
|
||||
--let $CHILD2_2_SELECT_TABLES2_BACKUP= $CHILD2_2_SELECT_TABLES2
|
||||
let $CHILD2_2_SELECT_TABLES2=
|
||||
SELECT value FROM tbl_b ORDER BY value;
|
||||
let $CHILD2_2_SELECT_ARGUMENT1=
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
|
||||
--let $CHILD2_3_DROP_TABLES_BACKUP= $CHILD2_3_DROP_TABLES
|
||||
let $CHILD2_3_DROP_TABLES=
|
||||
DROP TABLE IF EXISTS tbl_a;
|
||||
--let $CHILD2_3_CREATE_TABLES_BACKUP= $CHILD2_3_CREATE_TABLES
|
||||
let $CHILD2_3_CREATE_TABLES=
|
||||
CREATE TABLE tbl_a (
|
||||
value int NOT NULL,
|
||||
PRIMARY KEY(value)
|
||||
) $CHILD2_3_ENGINE $CHILD2_3_CHARSET;
|
||||
--let $CHILD2_3_SELECT_TABLES_BACKUP= $CHILD2_3_SELECT_TABLES
|
||||
let $CHILD2_3_SELECT_TABLES=
|
||||
SELECT value FROM tbl_a ORDER BY value;
|
||||
--let $CHILD2_3_DROP_TABLES2_BACKUP= $CHILD2_3_DROP_TABLES2
|
||||
let $CHILD2_3_DROP_TABLES2=
|
||||
DROP TABLE IF EXISTS tbl_b;
|
||||
--let $CHILD2_3_CREATE_TABLES2_BACKUP= $CHILD2_3_CREATE_TABLES2
|
||||
let $CHILD2_3_CREATE_TABLES2=
|
||||
CREATE TABLE tbl_b (
|
||||
value2 int NOT NULL,
|
||||
PRIMARY KEY(value2)
|
||||
) $CHILD2_3_ENGINE $CHILD2_3_CHARSET;
|
||||
--let $CHILD2_3_SELECT_TABLES2_BACKUP= $CHILD2_3_SELECT_TABLES2
|
||||
let $CHILD2_3_SELECT_TABLES2=
|
||||
SELECT value FROM tbl_b ORDER BY value;
|
||||
let $CHILD2_3_SELECT_ARGUMENT1=
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
|
||||
--let $OUTPUT_CHILD_GROUP2_BACKUP= $OUTPUT_CHILD_GROUP2
|
||||
--let $OUTPUT_CHILD_GROUP2= 1
|
||||
--let $USE_GENERAL_LOG_BACKUP= $USE_GENERAL_LOG
|
||||
--let $USE_GENERAL_LOG= 1
|
||||
105
storage/spider/mysql-test/spider/r/direct_join.result
Normal file
105
storage/spider/mysql-test/spider/r/direct_join.result
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
for master_1
|
||||
for child2
|
||||
child2_1
|
||||
child2_2
|
||||
child2_3
|
||||
for child3
|
||||
child3_1
|
||||
child3_2
|
||||
child3_3
|
||||
|
||||
drop and create databases
|
||||
connection master_1;
|
||||
DROP DATABASE IF EXISTS auto_test_local;
|
||||
CREATE DATABASE auto_test_local;
|
||||
USE auto_test_local;
|
||||
connection child2_1;
|
||||
SET @old_log_output = @@global.log_output;
|
||||
SET GLOBAL log_output = 'TABLE,FILE';
|
||||
DROP DATABASE IF EXISTS auto_test_remote;
|
||||
CREATE DATABASE auto_test_remote;
|
||||
USE auto_test_remote;
|
||||
|
||||
test select 1
|
||||
connection master_1;
|
||||
SELECT 1;
|
||||
1
|
||||
1
|
||||
connection child2_1;
|
||||
SELECT 1;
|
||||
1
|
||||
1
|
||||
|
||||
create table and insert
|
||||
connection child2_1;
|
||||
CHILD2_1_DROP_TABLES
|
||||
CHILD2_1_DROP_TABLES6
|
||||
CHILD2_1_DROP_TABLES5
|
||||
CHILD2_1_CREATE_TABLES
|
||||
CHILD2_1_CREATE_TABLES6
|
||||
CHILD2_1_CREATE_TABLES5
|
||||
TRUNCATE TABLE mysql.general_log;
|
||||
connection master_1;
|
||||
DROP TABLE IF EXISTS tbl_a;
|
||||
CREATE TABLE tbl_a (
|
||||
a INT DEFAULT 10,
|
||||
b CHAR(1) DEFAULT 'c',
|
||||
c DATETIME DEFAULT '1999-10-10 10:10:10',
|
||||
PRIMARY KEY(a),
|
||||
KEY idx1(b)
|
||||
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
|
||||
CREATE TABLE tbl_b (
|
||||
a INT DEFAULT 10,
|
||||
b CHAR(1) DEFAULT 'c',
|
||||
c DATETIME DEFAULT '1999-10-10 10:10:10'
|
||||
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT5_2_1
|
||||
CREATE TABLE tbl_c (
|
||||
a INT AUTO_INCREMENT,
|
||||
b INT DEFAULT 10,
|
||||
c INT DEFAULT 11,
|
||||
PRIMARY KEY(a),
|
||||
KEY idx1(b),
|
||||
KEY idx2(c)
|
||||
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT4_2_1
|
||||
insert into tbl_a values (1,'a','2000/01/01'),(2,'b','2000/01/02'),(3,'c','2000/01/03'),(4,'d','2000/01/04'),(5,'e','2000/01/05');
|
||||
insert into tbl_b values (1,'a','2000/01/01'),(2,'b','2000/01/02'),(3,'c','2000/01/03'),(4,'d','2000/01/04'),(5,'e','2000/01/05');
|
||||
insert into tbl_c values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500);
|
||||
|
||||
select test
|
||||
connection child2_1;
|
||||
TRUNCATE TABLE mysql.general_log;
|
||||
connection master_1;
|
||||
SELECT a.a, c.b, c.c FROM tbl_a a, tbl_b b, tbl_c c WHERE a.a = b.a and a.a = c.a ORDER BY a.b DESC LIMIT 1,2;
|
||||
a b c
|
||||
4 40 400
|
||||
3 30 300
|
||||
connection child2_1;
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
|
||||
argument
|
||||
select t0.`b` `b`,t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r` t0,`auto_test_remote`.`ta_r_3` t1,`auto_test_remote`.`ta_r_int` t2 where ((t0.`a` = t1.`a`) and (t2.`a` = t1.`a`)) order by t0.`b` desc limit 1,2
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
|
||||
SELECT a, b, date_format(c, '%Y-%m-%d %H:%i:%s') FROM ta_r ORDER BY a;
|
||||
a b date_format(c, '%Y-%m-%d %H:%i:%s')
|
||||
1 a 2000-01-01 00:00:00
|
||||
2 b 2000-01-02 00:00:00
|
||||
3 c 2000-01-03 00:00:00
|
||||
4 d 2000-01-04 00:00:00
|
||||
5 e 2000-01-05 00:00:00
|
||||
|
||||
deinit
|
||||
connection master_1;
|
||||
DROP DATABASE IF EXISTS auto_test_local;
|
||||
connection child2_1;
|
||||
DROP DATABASE IF EXISTS auto_test_remote;
|
||||
SET GLOBAL log_output = @old_log_output;
|
||||
for master_1
|
||||
for child2
|
||||
child2_1
|
||||
child2_2
|
||||
child2_3
|
||||
for child3
|
||||
child3_1
|
||||
child3_2
|
||||
child3_3
|
||||
|
||||
end of test
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
for master_1
|
||||
for child2
|
||||
child2_1
|
||||
child2_2
|
||||
child2_3
|
||||
for child3
|
||||
child3_1
|
||||
child3_2
|
||||
child3_3
|
||||
|
||||
drop and create databases
|
||||
connection master_1;
|
||||
DROP DATABASE IF EXISTS auto_test_local;
|
||||
CREATE DATABASE auto_test_local;
|
||||
USE auto_test_local;
|
||||
connection child2_1;
|
||||
SET @old_log_output = @@global.log_output;
|
||||
SET GLOBAL log_output = 'TABLE,FILE';
|
||||
DROP DATABASE IF EXISTS auto_test_remote;
|
||||
CREATE DATABASE auto_test_remote;
|
||||
USE auto_test_remote;
|
||||
connection child2_2;
|
||||
SET @old_log_output = @@global.log_output;
|
||||
SET GLOBAL log_output = 'TABLE,FILE';
|
||||
DROP DATABASE IF EXISTS auto_test_remote2;
|
||||
CREATE DATABASE auto_test_remote2;
|
||||
USE auto_test_remote2;
|
||||
connection child2_3;
|
||||
SET @old_log_output = @@global.log_output;
|
||||
SET GLOBAL log_output = 'TABLE,FILE';
|
||||
DROP DATABASE IF EXISTS auto_test_remote3;
|
||||
CREATE DATABASE auto_test_remote3;
|
||||
USE auto_test_remote3;
|
||||
|
||||
create table and insert
|
||||
connection child2_1;
|
||||
CHILD2_1_DROP_TABLES
|
||||
CHILD2_1_DROP_TABLES2
|
||||
CHILD2_1_CREATE_TABLES
|
||||
CHILD2_1_CREATE_TABLES2
|
||||
TRUNCATE TABLE mysql.general_log;
|
||||
connection child2_2;
|
||||
CHILD2_2_DROP_TABLES
|
||||
CHILD2_2_DROP_TABLES2
|
||||
CHILD2_2_CREATE_TABLES
|
||||
CHILD2_2_CREATE_TABLES2
|
||||
TRUNCATE TABLE mysql.general_log;
|
||||
connection child2_3;
|
||||
CHILD2_3_DROP_TABLES
|
||||
CHILD2_3_DROP_TABLES2
|
||||
CHILD2_3_CREATE_TABLES
|
||||
CHILD2_3_CREATE_TABLES2
|
||||
TRUNCATE TABLE mysql.general_log;
|
||||
connection master_1;
|
||||
DROP TABLE IF EXISTS tbl_a;
|
||||
DROP TABLE IF EXISTS tbl_b;
|
||||
CREATE TABLE tbl_a (
|
||||
value int NOT NULL,
|
||||
PRIMARY KEY(value)
|
||||
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1
|
||||
CREATE TABLE tbl_b (
|
||||
value2 int NOT NULL,
|
||||
PRIMARY KEY(value2)
|
||||
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_2
|
||||
insert into tbl_a values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||
insert into tbl_b values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||
connection master_1;
|
||||
SELECT sum(a.value), count(b.value2) FROM tbl_a a, tbl_b b WHERE a.value = b.value2 AND a.value = 5;
|
||||
sum(a.value) count(b.value2)
|
||||
5 1
|
||||
SELECT sum(a.value), count(b.value2) FROM tbl_a a, tbl_b b WHERE a.value = 5 and b.value2 = 5;
|
||||
sum(a.value) count(b.value2)
|
||||
5 1
|
||||
connection child2_1;
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
|
||||
argument
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
|
||||
SELECT value FROM tbl_a ORDER BY value;
|
||||
value
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
connection child2_2;
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
|
||||
argument
|
||||
select `value` from `auto_test_remote2`.`tbl_a` where `value` = 5
|
||||
select `value2` from `auto_test_remote2`.`tbl_b` where `value2` = 5
|
||||
select `value` from `auto_test_remote2`.`tbl_a` where `value` = 5
|
||||
select `value2` from `auto_test_remote2`.`tbl_b` where `value2` = 5
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
|
||||
SELECT value FROM tbl_a ORDER BY value;
|
||||
value
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
connection child2_3;
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
|
||||
argument
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
|
||||
SELECT value FROM tbl_a ORDER BY value;
|
||||
value
|
||||
10
|
||||
|
||||
deinit
|
||||
connection master_1;
|
||||
DROP DATABASE IF EXISTS auto_test_local;
|
||||
connection child2_1;
|
||||
DROP DATABASE IF EXISTS auto_test_remote;
|
||||
SET GLOBAL log_output = @old_log_output;
|
||||
connection child2_2;
|
||||
DROP DATABASE IF EXISTS auto_test_remote2;
|
||||
SET GLOBAL log_output = @old_log_output;
|
||||
connection child2_3;
|
||||
DROP DATABASE IF EXISTS auto_test_remote3;
|
||||
SET GLOBAL log_output = @old_log_output;
|
||||
connection master_1;
|
||||
for master_1
|
||||
for child2
|
||||
child2_1
|
||||
child2_2
|
||||
child2_3
|
||||
for child3
|
||||
child3_1
|
||||
child3_2
|
||||
child3_3
|
||||
|
||||
end of test
|
||||
197
storage/spider/mysql-test/spider/t/direct_join.test
Normal file
197
storage/spider/mysql-test/spider/t/direct_join.test
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
--source ../include/direct_join_init.inc
|
||||
|
||||
--echo
|
||||
--echo drop and create databases
|
||||
--connection master_1
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS auto_test_local;
|
||||
CREATE DATABASE auto_test_local;
|
||||
USE auto_test_local;
|
||||
if ($USE_CHILD_GROUP2)
|
||||
{
|
||||
--connection child2_1
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
SET @old_log_output = @@global.log_output;
|
||||
SET GLOBAL log_output = 'TABLE,FILE';
|
||||
}
|
||||
DROP DATABASE IF EXISTS auto_test_remote;
|
||||
CREATE DATABASE auto_test_remote;
|
||||
USE auto_test_remote;
|
||||
}
|
||||
--enable_warnings
|
||||
|
||||
--echo
|
||||
--echo test select 1
|
||||
--connection master_1
|
||||
SELECT 1;
|
||||
if ($USE_CHILD_GROUP2)
|
||||
{
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
}
|
||||
--connection child2_1
|
||||
SELECT 1;
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
}
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo create table and insert
|
||||
if ($USE_CHILD_GROUP2)
|
||||
{
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
}
|
||||
--connection child2_1
|
||||
if ($OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--disable_query_log
|
||||
echo CHILD2_1_DROP_TABLES;
|
||||
echo CHILD2_1_DROP_TABLES6;
|
||||
echo CHILD2_1_DROP_TABLES5;
|
||||
echo CHILD2_1_CREATE_TABLES;
|
||||
echo CHILD2_1_CREATE_TABLES6;
|
||||
echo CHILD2_1_CREATE_TABLES5;
|
||||
}
|
||||
--disable_warnings
|
||||
eval $CHILD2_1_DROP_TABLES;
|
||||
eval $CHILD2_1_DROP_TABLES6;
|
||||
eval $CHILD2_1_DROP_TABLES5;
|
||||
--enable_warnings
|
||||
eval $CHILD2_1_CREATE_TABLES;
|
||||
eval $CHILD2_1_CREATE_TABLES6;
|
||||
eval $CHILD2_1_CREATE_TABLES5;
|
||||
if ($OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--enable_query_log
|
||||
}
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
TRUNCATE TABLE mysql.general_log;
|
||||
}
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
}
|
||||
}
|
||||
--connection master_1
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS tbl_a;
|
||||
--enable_warnings
|
||||
--disable_query_log
|
||||
echo CREATE TABLE tbl_a (
|
||||
a INT DEFAULT 10,
|
||||
b CHAR(1) DEFAULT 'c',
|
||||
c DATETIME DEFAULT '1999-10-10 10:10:10',
|
||||
PRIMARY KEY(a),
|
||||
KEY idx1(b)
|
||||
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
|
||||
eval CREATE TABLE tbl_a (
|
||||
a INT DEFAULT 10,
|
||||
b CHAR(1) DEFAULT 'c',
|
||||
c DATETIME DEFAULT '1999-10-10 10:10:10',
|
||||
PRIMARY KEY(a),
|
||||
KEY idx1(b)
|
||||
) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
|
||||
echo CREATE TABLE tbl_b (
|
||||
a INT DEFAULT 10,
|
||||
b CHAR(1) DEFAULT 'c',
|
||||
c DATETIME DEFAULT '1999-10-10 10:10:10'
|
||||
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT5_2_1;
|
||||
eval CREATE TABLE tbl_b (
|
||||
a INT DEFAULT 10,
|
||||
b CHAR(1) DEFAULT 'c',
|
||||
c DATETIME DEFAULT '1999-10-10 10:10:10'
|
||||
) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT5_2_1;
|
||||
echo CREATE TABLE tbl_c (
|
||||
a INT AUTO_INCREMENT,
|
||||
b INT DEFAULT 10,
|
||||
c INT DEFAULT 11,
|
||||
PRIMARY KEY(a),
|
||||
KEY idx1(b),
|
||||
KEY idx2(c)
|
||||
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT4_2_1;
|
||||
eval CREATE TABLE tbl_c (
|
||||
a INT AUTO_INCREMENT,
|
||||
b INT DEFAULT 10,
|
||||
c INT DEFAULT 11,
|
||||
PRIMARY KEY(a),
|
||||
KEY idx1(b),
|
||||
KEY idx2(c)
|
||||
) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT4_2_1;
|
||||
--enable_query_log
|
||||
insert into tbl_a values (1,'a','2000/01/01'),(2,'b','2000/01/02'),(3,'c','2000/01/03'),(4,'d','2000/01/04'),(5,'e','2000/01/05');
|
||||
insert into tbl_b values (1,'a','2000/01/01'),(2,'b','2000/01/02'),(3,'c','2000/01/03'),(4,'d','2000/01/04'),(5,'e','2000/01/05');
|
||||
insert into tbl_c values (1,10,100),(2,20,200),(3,30,300),(4,40,400),(5,50,500);
|
||||
|
||||
--echo
|
||||
--echo select test
|
||||
if ($USE_CHILD_GROUP2)
|
||||
{
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
}
|
||||
--connection child2_1
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
TRUNCATE TABLE mysql.general_log;
|
||||
}
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
}
|
||||
}
|
||||
|
||||
--connection master_1
|
||||
SELECT a.a, c.b, c.c FROM tbl_a a, tbl_b b, tbl_c c WHERE a.a = b.a and a.a = c.a ORDER BY a.b DESC LIMIT 1,2;
|
||||
|
||||
if ($USE_CHILD_GROUP2)
|
||||
{
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
}
|
||||
--connection child2_1
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
eval $CHILD2_1_SELECT_ARGUMENT1;
|
||||
}
|
||||
eval $CHILD2_1_SELECT_TABLES;
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
}
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo deinit
|
||||
--disable_warnings
|
||||
--connection master_1
|
||||
DROP DATABASE IF EXISTS auto_test_local;
|
||||
if ($USE_CHILD_GROUP2)
|
||||
{
|
||||
--connection child2_1
|
||||
DROP DATABASE IF EXISTS auto_test_remote;
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
SET GLOBAL log_output = @old_log_output;
|
||||
}
|
||||
}
|
||||
--enable_warnings
|
||||
--source ../include/direct_join_deinit.inc
|
||||
--echo
|
||||
--echo end of test
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
--source ../include/partition_join_pushdown_for_single_partition_init.inc
|
||||
if (!$HAVE_PARTITION)
|
||||
{
|
||||
--source ../include/partition_join_pushdown_for_single_partition_deinit.inc
|
||||
skip Test requires partitioning;
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo drop and create databases
|
||||
--connection master_1
|
||||
--disable_warnings
|
||||
DROP DATABASE IF EXISTS auto_test_local;
|
||||
CREATE DATABASE auto_test_local;
|
||||
USE auto_test_local;
|
||||
if ($USE_CHILD_GROUP2)
|
||||
{
|
||||
--connection child2_1
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
SET @old_log_output = @@global.log_output;
|
||||
SET GLOBAL log_output = 'TABLE,FILE';
|
||||
}
|
||||
DROP DATABASE IF EXISTS auto_test_remote;
|
||||
CREATE DATABASE auto_test_remote;
|
||||
USE auto_test_remote;
|
||||
--connection child2_2
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
SET @old_log_output = @@global.log_output;
|
||||
SET GLOBAL log_output = 'TABLE,FILE';
|
||||
}
|
||||
DROP DATABASE IF EXISTS auto_test_remote2;
|
||||
CREATE DATABASE auto_test_remote2;
|
||||
USE auto_test_remote2;
|
||||
--connection child2_3
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
SET @old_log_output = @@global.log_output;
|
||||
SET GLOBAL log_output = 'TABLE,FILE';
|
||||
}
|
||||
DROP DATABASE IF EXISTS auto_test_remote3;
|
||||
CREATE DATABASE auto_test_remote3;
|
||||
USE auto_test_remote3;
|
||||
}
|
||||
--enable_warnings
|
||||
|
||||
--echo
|
||||
--echo create table and insert
|
||||
if ($USE_CHILD_GROUP2)
|
||||
{
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
}
|
||||
--connection child2_1
|
||||
if ($OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--disable_query_log
|
||||
echo CHILD2_1_DROP_TABLES;
|
||||
echo CHILD2_1_DROP_TABLES2;
|
||||
echo CHILD2_1_CREATE_TABLES;
|
||||
echo CHILD2_1_CREATE_TABLES2;
|
||||
}
|
||||
--disable_warnings
|
||||
eval $CHILD2_1_DROP_TABLES;
|
||||
eval $CHILD2_1_DROP_TABLES2;
|
||||
--enable_warnings
|
||||
eval $CHILD2_1_CREATE_TABLES;
|
||||
eval $CHILD2_1_CREATE_TABLES2;
|
||||
if ($OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--enable_query_log
|
||||
}
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
TRUNCATE TABLE mysql.general_log;
|
||||
}
|
||||
--connection child2_2
|
||||
if ($OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--disable_query_log
|
||||
echo CHILD2_2_DROP_TABLES;
|
||||
echo CHILD2_2_DROP_TABLES2;
|
||||
echo CHILD2_2_CREATE_TABLES;
|
||||
echo CHILD2_2_CREATE_TABLES2;
|
||||
}
|
||||
--disable_warnings
|
||||
eval $CHILD2_2_DROP_TABLES;
|
||||
eval $CHILD2_2_DROP_TABLES2;
|
||||
--enable_warnings
|
||||
eval $CHILD2_2_CREATE_TABLES;
|
||||
eval $CHILD2_2_CREATE_TABLES2;
|
||||
if ($OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--enable_query_log
|
||||
}
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
TRUNCATE TABLE mysql.general_log;
|
||||
}
|
||||
--connection child2_3
|
||||
if ($OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--disable_query_log
|
||||
echo CHILD2_3_DROP_TABLES;
|
||||
echo CHILD2_3_DROP_TABLES2;
|
||||
echo CHILD2_3_CREATE_TABLES;
|
||||
echo CHILD2_3_CREATE_TABLES2;
|
||||
}
|
||||
--disable_warnings
|
||||
eval $CHILD2_3_DROP_TABLES;
|
||||
eval $CHILD2_3_DROP_TABLES2;
|
||||
--enable_warnings
|
||||
eval $CHILD2_3_CREATE_TABLES;
|
||||
eval $CHILD2_3_CREATE_TABLES2;
|
||||
if ($OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--enable_query_log
|
||||
}
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
TRUNCATE TABLE mysql.general_log;
|
||||
}
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
}
|
||||
}
|
||||
--connection master_1
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS tbl_a;
|
||||
DROP TABLE IF EXISTS tbl_b;
|
||||
--enable_warnings
|
||||
--disable_query_log
|
||||
echo CREATE TABLE tbl_a (
|
||||
value int NOT NULL,
|
||||
PRIMARY KEY(value)
|
||||
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1;
|
||||
eval CREATE TABLE tbl_a (
|
||||
value int NOT NULL,
|
||||
PRIMARY KEY(value)
|
||||
) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1;
|
||||
echo CREATE TABLE tbl_b (
|
||||
value2 int NOT NULL,
|
||||
PRIMARY KEY(value2)
|
||||
) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_2;
|
||||
eval CREATE TABLE tbl_b (
|
||||
value2 int NOT NULL,
|
||||
PRIMARY KEY(value2)
|
||||
) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_2;
|
||||
--enable_query_log
|
||||
|
||||
insert into tbl_a values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||
insert into tbl_b values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||
|
||||
--connection master_1
|
||||
SELECT sum(a.value), count(b.value2) FROM tbl_a a, tbl_b b WHERE a.value = b.value2 AND a.value = 5;
|
||||
SELECT sum(a.value), count(b.value2) FROM tbl_a a, tbl_b b WHERE a.value = 5 and b.value2 = 5;
|
||||
if ($USE_CHILD_GROUP2)
|
||||
{
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
}
|
||||
--connection child2_1
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
eval $CHILD2_1_SELECT_ARGUMENT1;
|
||||
}
|
||||
eval $CHILD2_1_SELECT_TABLES;
|
||||
--connection child2_2
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
eval $CHILD2_2_SELECT_ARGUMENT1;
|
||||
}
|
||||
eval $CHILD2_2_SELECT_TABLES;
|
||||
--connection child2_3
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
eval $CHILD2_3_SELECT_ARGUMENT1;
|
||||
}
|
||||
eval $CHILD2_3_SELECT_TABLES;
|
||||
if (!$OUTPUT_CHILD_GROUP2)
|
||||
{
|
||||
--enable_query_log
|
||||
--enable_result_log
|
||||
}
|
||||
}
|
||||
|
||||
--echo
|
||||
--echo deinit
|
||||
--disable_warnings
|
||||
--connection master_1
|
||||
DROP DATABASE IF EXISTS auto_test_local;
|
||||
if ($USE_CHILD_GROUP2)
|
||||
{
|
||||
--connection child2_1
|
||||
DROP DATABASE IF EXISTS auto_test_remote;
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
SET GLOBAL log_output = @old_log_output;
|
||||
}
|
||||
--connection child2_2
|
||||
DROP DATABASE IF EXISTS auto_test_remote2;
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
SET GLOBAL log_output = @old_log_output;
|
||||
}
|
||||
--connection child2_3
|
||||
DROP DATABASE IF EXISTS auto_test_remote3;
|
||||
if ($USE_GENERAL_LOG)
|
||||
{
|
||||
SET GLOBAL log_output = @old_log_output;
|
||||
}
|
||||
}
|
||||
--enable_warnings
|
||||
--source ../include/partition_join_pushdown_for_single_partition_deinit.inc
|
||||
--echo
|
||||
--echo end of test
|
||||
|
|
@ -347,7 +347,7 @@ bool spider_conn_need_open_handler(
|
|||
int link_idx
|
||||
);
|
||||
|
||||
SPIDER_IP_PORT_CONN *spider_create_ipport_conn(SPIDER_CONN *conn) ;
|
||||
SPIDER_IP_PORT_CONN *spider_create_ipport_conn(SPIDER_CONN *conn);
|
||||
SPIDER_CONN* spider_get_conn_from_idle_connection
|
||||
(
|
||||
SPIDER_SHARE *share,
|
||||
|
|
|
|||
|
|
@ -8740,15 +8740,12 @@ int spider_db_open_item_field(
|
|||
Field *field = item_field->field;
|
||||
SPIDER_SHARE *share = spider->share;
|
||||
DBUG_ENTER("spider_db_open_item_field");
|
||||
if (field)
|
||||
if (field && !field->table->const_table)
|
||||
{
|
||||
DBUG_PRINT("info",("spider field=%p", field));
|
||||
DBUG_PRINT("info",("spider db=%s", field->table->s->db.str));
|
||||
DBUG_PRINT("info",("spider table_name=%s", field->table->s->table_name.str));
|
||||
DBUG_PRINT("info",("spider tmp_table=%u", field->table->s->tmp_table));
|
||||
/*
|
||||
if (field->table->const_table)
|
||||
*/
|
||||
if (field->table->s->tmp_table != INTERNAL_TMP_TABLE)
|
||||
{
|
||||
if (!use_fields)
|
||||
|
|
|
|||
|
|
@ -27,11 +27,12 @@
|
|||
#define SPIDER_SUPPORT_CREATE_OR_REPLACE_TABLE
|
||||
#endif
|
||||
|
||||
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100204
|
||||
#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100211
|
||||
#define HANDLER_HAS_TOP_TABLE_FIELDS
|
||||
#define HANDLER_HAS_DIRECT_UPDATE_ROWS
|
||||
#define HANDLER_HAS_DIRECT_AGGREGATE
|
||||
#define PARTITION_HAS_GET_CHILD_HANDLERS
|
||||
#define PARTITION_HAS_GET_PART_SPEC
|
||||
#define HA_EXTRA_HAS_STARTING_ORDERED_INDEX_SCAN
|
||||
#define HANDLER_HAS_NEED_INFO_FOR_AUTO_INC
|
||||
#define HANDLER_HAS_CAN_USE_FOR_AUTO_INC_INIT
|
||||
|
|
|
|||
|
|
@ -1582,6 +1582,8 @@ group_by_handler *spider_create_group_by_handler(
|
|||
from = query->from;
|
||||
do {
|
||||
DBUG_PRINT("info",("spider from=%p", from));
|
||||
if (from->table->const_table)
|
||||
continue;
|
||||
if (from->table->part_info)
|
||||
{
|
||||
DBUG_PRINT("info",("spider partition handler"));
|
||||
|
|
@ -1608,6 +1610,15 @@ group_by_handler *spider_create_group_by_handler(
|
|||
|
||||
table_idx = 0;
|
||||
from = query->from;
|
||||
while (from && from->table->const_table)
|
||||
{
|
||||
from = from->next_local;
|
||||
}
|
||||
if (!from)
|
||||
{
|
||||
/* all tables are const_table */
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
|
||||
if (from->table->part_info)
|
||||
{
|
||||
|
|
@ -1637,6 +1648,8 @@ group_by_handler *spider_create_group_by_handler(
|
|||
}
|
||||
while ((from = from->next_local))
|
||||
{
|
||||
if (from->table->const_table)
|
||||
continue;
|
||||
#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
|
||||
if (from->table->part_info)
|
||||
{
|
||||
|
|
@ -1673,6 +1686,8 @@ group_by_handler *spider_create_group_by_handler(
|
|||
|
||||
from = query->from;
|
||||
do {
|
||||
if (from->table->const_table)
|
||||
continue;
|
||||
#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
|
||||
if (from->table->part_info)
|
||||
{
|
||||
|
|
@ -1807,6 +1822,10 @@ group_by_handler *spider_create_group_by_handler(
|
|||
}
|
||||
|
||||
from = query->from;
|
||||
while (from->table->const_table)
|
||||
{
|
||||
from = from->next_local;
|
||||
}
|
||||
#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
|
||||
if (from->table->part_info)
|
||||
{
|
||||
|
|
@ -1891,6 +1910,8 @@ group_by_handler *spider_create_group_by_handler(
|
|||
|
||||
while ((from = from->next_local))
|
||||
{
|
||||
if (from->table->const_table)
|
||||
continue;
|
||||
fields->clear_conn_holder_from_conn();
|
||||
|
||||
#if defined(PARTITION_HAS_GET_CHILD_HANDLERS) && defined(PARTITION_HAS_GET_PART_SPEC)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue