mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
MDEV-26345 Spider GBH should execute original queries on the data node
Stop skipping const items when selecting but skip them when storing their results to spider row to avoid storing in mismatching temporary table fields. Skip auxiliary fields in SELECTing, and do not store the (non-existing) results to the corresponding temporary table accordingly. When there are BOTH auxiliary fields AND const items in the auxiliary field items, do not use the spider GBH. This is a rare occasion if it happens at all and not worth the added complexity to cover it. Use the original item (item_ptr) in constructing GROUP BY and ORDER BY, which also means using item->name instead of field->field_name as aliases in constructing SELECT items. This fixes spurious regressions caused by the above changes in some tests using ORDER BY, such as mdev_24517.test. As a by-product, this also fixes MDEV-29546. Therefore we update mdev_29008.test to include the MDEV-29546 case.
This commit is contained in:
parent
e6daff40e4
commit
77ed235d50
22 changed files with 286 additions and 109 deletions
|
@ -53,6 +53,8 @@ class Select_limit_counters;
|
|||
struct Query
|
||||
{
|
||||
List<Item> *select;
|
||||
/* Number of auxiliary fields. */
|
||||
int n_aux;
|
||||
bool distinct;
|
||||
TABLE_LIST *from;
|
||||
Item *where;
|
||||
|
@ -71,7 +73,10 @@ public:
|
|||
|
||||
/*
|
||||
Temporary table where all results should be stored in record[0]
|
||||
The table has a field for every item from the Query::select list.
|
||||
The table has a field for every item from the Query::select list,
|
||||
except for const items and some other exceptions, see
|
||||
Create_tmp_table::add_fields() for which items are included and
|
||||
which are skipped.
|
||||
*/
|
||||
TABLE *table;
|
||||
|
||||
|
|
|
@ -3400,7 +3400,9 @@ bool JOIN::make_aggr_tables_info()
|
|||
original DISTINCT. Thus, we set select_distinct || group_optimized_away
|
||||
to Query::distinct.
|
||||
*/
|
||||
Query query= {&all_fields, select_distinct || group_optimized_away,
|
||||
Query query= {&all_fields,
|
||||
(int) all_fields.elements - (int) fields_list.elements,
|
||||
select_distinct || group_optimized_away,
|
||||
tables_list, conds,
|
||||
group_list, order ? order : group_list, having,
|
||||
&select_lex->master_unit()->lim};
|
||||
|
|
|
@ -1473,7 +1473,7 @@ public:
|
|||
|
||||
Then, ORDER/GROUP BY and Window Function code add columns that need to
|
||||
be saved to be available in the post-group-by context. These extra columns
|
||||
are added to the front, because this->all_fields points to the suffix of
|
||||
are added to the front, because this->fields_list points to the suffix of
|
||||
this list.
|
||||
*/
|
||||
List<Item> all_fields;
|
||||
|
|
|
@ -52,13 +52,9 @@ extern pthread_mutex_t spider_lgtm_tblhnd_share_mutex;
|
|||
/* UTC time zone for timestamp columns */
|
||||
extern Time_zone *UTC;
|
||||
|
||||
ha_spider::ha_spider(
|
||||
) : handler(spider_hton_ptr, NULL)
|
||||
void ha_spider::init_fields()
|
||||
{
|
||||
DBUG_ENTER("ha_spider::ha_spider");
|
||||
DBUG_PRINT("info",("spider this=%p", this));
|
||||
spider_alloc_calc_mem_init(mem_calc, SPD_MID_HA_SPIDER_HA_SPIDER_1);
|
||||
spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this));
|
||||
DBUG_ENTER("ha_spider::init_fields");
|
||||
share = NULL;
|
||||
conns = NULL;
|
||||
need_mons = NULL;
|
||||
|
@ -113,6 +109,20 @@ ha_spider::ha_spider(
|
|||
result_list.casual_read = NULL;
|
||||
result_list.use_both_key = FALSE;
|
||||
result_list.in_cmp_ref = FALSE;
|
||||
result_list.skips= NULL;
|
||||
result_list.n_aux= 0;
|
||||
ref_length = sizeof(SPIDER_POSITION);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
ha_spider::ha_spider(
|
||||
) : handler(spider_hton_ptr, NULL)
|
||||
{
|
||||
DBUG_ENTER("ha_spider::ha_spider");
|
||||
DBUG_PRINT("info",("spider this=%p", this));
|
||||
spider_alloc_calc_mem_init(mem_calc, SPD_MID_HA_SPIDER_HA_SPIDER_1);
|
||||
spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this));
|
||||
init_fields();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -125,61 +135,7 @@ ha_spider::ha_spider(
|
|||
DBUG_PRINT("info",("spider this=%p", this));
|
||||
spider_alloc_calc_mem_init(mem_calc, SPD_MID_HA_SPIDER_HA_SPIDER_2);
|
||||
spider_alloc_calc_mem(spider_current_trx, mem_calc, sizeof(*this));
|
||||
share = NULL;
|
||||
conns = NULL;
|
||||
need_mons = NULL;
|
||||
blob_buff = NULL;
|
||||
conn_keys = NULL;
|
||||
spider_thread_id = 0;
|
||||
trx_conn_adjustment = 0;
|
||||
search_link_query_id = 0;
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
partition_handler = NULL;
|
||||
#endif
|
||||
#ifdef HA_MRR_USE_DEFAULT_IMPL
|
||||
multi_range_keys = NULL;
|
||||
mrr_key_buff = NULL;
|
||||
#endif
|
||||
append_tblnm_alias = NULL;
|
||||
use_index_merge = FALSE;
|
||||
is_clone = FALSE;
|
||||
pt_clone_source_handler = NULL;
|
||||
pt_clone_last_searcher = NULL;
|
||||
ft_handler = NULL;
|
||||
ft_first = NULL;
|
||||
ft_current = NULL;
|
||||
ft_count = 0;
|
||||
ft_init_without_index_init = FALSE;
|
||||
sql_kinds = 0;
|
||||
error_mode = 0;
|
||||
use_spatial_index = FALSE;
|
||||
use_fields = FALSE;
|
||||
dml_inited = FALSE;
|
||||
use_pre_call = FALSE;
|
||||
use_pre_action = FALSE;
|
||||
do_direct_update = FALSE;
|
||||
prev_index_rnd_init = SPD_NONE;
|
||||
direct_aggregate_item_first = NULL;
|
||||
result_link_idx = 0;
|
||||
result_list.have_sql_kind_backup = FALSE;
|
||||
result_list.sqls = NULL;
|
||||
result_list.insert_sqls = NULL;
|
||||
result_list.update_sqls = NULL;
|
||||
result_list.tmp_sqls = NULL;
|
||||
result_list.tmp_tables_created = FALSE;
|
||||
result_list.bgs_working = FALSE;
|
||||
result_list.direct_order_limit = FALSE;
|
||||
result_list.direct_limit_offset = FALSE;
|
||||
result_list.set_split_read = FALSE;
|
||||
result_list.insert_dup_update_pushdown = FALSE;
|
||||
result_list.tmp_pos_row_first = NULL;
|
||||
result_list.direct_aggregate = FALSE;
|
||||
result_list.snap_direct_aggregate = FALSE;
|
||||
result_list.direct_distinct = FALSE;
|
||||
result_list.casual_read = NULL;
|
||||
result_list.use_both_key = FALSE;
|
||||
result_list.in_cmp_ref = FALSE;
|
||||
ref_length = sizeof(SPIDER_POSITION);
|
||||
init_fields();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
|
|
@ -910,6 +910,8 @@ public:
|
|||
int append_lock_tables_list();
|
||||
int lock_tables();
|
||||
int dml_init();
|
||||
private:
|
||||
void init_fields();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -54,13 +54,13 @@ m const val sq
|
|||
connection child2_1;
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
|
||||
argument
|
||||
select t0.`id` `id`,t0.`val` `val` from `auto_test_remote`.`tbl_a` t0
|
||||
select t0.`id` `id`,t0.`val` `val`,(t0.`val` + 10) `val+10` from `auto_test_remote`.`tbl_a` t0
|
||||
select t0.`id` `id`,0 `const`,t0.`val` `val` from `auto_test_remote`.`tbl_a` t0
|
||||
select `id`,`val` from `auto_test_remote`.`tbl_a`
|
||||
select (t0.`val` + 1) `tbl_a.val+1` from `auto_test_remote`.`tbl_a` t0
|
||||
select `id`,`val` from `auto_test_remote`.`tbl_a` order by `id` desc limit 1 for update
|
||||
select (t0.`val` + 10) `val+10`,t0.`val` `val` from `auto_test_remote`.`tbl_a` t0 group by t0.`val` order by t0.`val`
|
||||
select `val` from `auto_test_remote`.`tbl_a` group by `val`
|
||||
select (t0.`val` + 1) `tbl_a.val+1` from `auto_test_remote`.`tbl_a` t0 limit 1
|
||||
select max(t0.`id`) `m`,t0.`val` `val` from `auto_test_remote`.`tbl_a` t0 group by t0.`val` order by t0.`val`
|
||||
select max(`id`),min(`id`),`val` from `auto_test_remote`.`tbl_a` group by `val`
|
||||
select (t0.`val` + 1) `tbl_a.val+1` from `auto_test_remote`.`tbl_a` t0 limit 1
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
|
||||
SELECT id, val FROM tbl_a ORDER BY id;
|
||||
|
|
48
storage/spider/mysql-test/spider/bugfix/r/mdev_26345.result
Normal file
48
storage/spider/mysql-test/spider/bugfix/r/mdev_26345.result
Normal file
|
@ -0,0 +1,48 @@
|
|||
for master_1
|
||||
for child2
|
||||
for child3
|
||||
|
||||
MDEV-26345 SELECT MIN on Spider table returns more rows than expected
|
||||
|
||||
set spider_same_server_link= 1;
|
||||
CREATE SERVER srv FOREIGN DATA WRAPPER mysql
|
||||
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
|
||||
create table t2 (a int, b int, PRIMARY KEY (a, b));
|
||||
create table t1 (a int, b int, PRIMARY KEY (a, b)) ENGINE=Spider
|
||||
COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
|
||||
insert into t1 VALUES (1,4), (1,2), (2,11);
|
||||
SELECT MIN(b), a FROM t1 WHERE a=1;
|
||||
MIN(b) a
|
||||
2 1
|
||||
SELECT MAX(b), a FROM t1 WHERE a<3;
|
||||
MAX(b) a
|
||||
11 1
|
||||
drop table t1, t2;
|
||||
create table t2 (a int, b int, c int, PRIMARY KEY (a, b));
|
||||
create table t1 (a int, b int, c int, PRIMARY KEY (a, b)) ENGINE=Spider
|
||||
COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
|
||||
insert into t2 VALUES (1,4,1), (1,2,2), (2,11,3);
|
||||
SELECT MIN(b), a, c FROM t1 WHERE a=1;
|
||||
MIN(b) a c
|
||||
2 1 2
|
||||
drop table t1, t2;
|
||||
create table t2 (a int, b int);
|
||||
create table t1 ENGINE=Spider
|
||||
COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
|
||||
insert into t1 VALUES (1,1), (1,1), (2,2), (2,2);
|
||||
select distinct count(a) from t1 group by b;
|
||||
count(a)
|
||||
2
|
||||
drop table t1, t2;
|
||||
create table t2 (c int);
|
||||
create table t1 (c int) ENGINE=Spider
|
||||
COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
|
||||
insert into t1 values (1),(3),(5),(7),(9),(11),(13),(15);
|
||||
select count(c) as d from t1 having d > 5;
|
||||
d
|
||||
8
|
||||
drop table t1, t2;
|
||||
drop server srv;
|
||||
for master_1
|
||||
for child2
|
||||
for child3
|
|
@ -15,6 +15,10 @@ a INT,
|
|||
b INT
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
INSERT INTO tbl_a VALUES (1,2),(3,4);
|
||||
set @old_general_log=@@global.general_log;
|
||||
set global general_log=1;
|
||||
set @old_log_output=@@global.log_output;
|
||||
set global log_output="TABLE";
|
||||
connection master_1;
|
||||
CREATE DATABASE auto_test_local;
|
||||
USE auto_test_local;
|
||||
|
@ -26,9 +30,20 @@ SELECT MIN(t2.a) AS f1, t1.b AS f2 FROM tbl_a AS t1 JOIN tbl_a AS t2 GROUP BY f2
|
|||
f1 f2
|
||||
1 2
|
||||
1 4
|
||||
SELECT MIN(t2.a) AS f1, t1.b AS f2 FROM tbl_a AS t1 JOIN tbl_a AS t2 GROUP BY f2 ORDER BY MIN(t2.a), MAX(t2.a), f2;
|
||||
f1 f2
|
||||
1 2
|
||||
1 4
|
||||
connection master_1;
|
||||
DROP DATABASE IF EXISTS auto_test_local;
|
||||
connection child2_1;
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE 'select %';
|
||||
argument
|
||||
select min(t1.`a`) `f1`,t0.`b` `f2` from `auto_test_remote`.`tbl_a` t0 join `auto_test_remote`.`tbl_a` t1 group by `f2` order by `f1`,`f2`
|
||||
select min(t1.`a`) `f1`,t0.`b` `f2` from `auto_test_remote`.`tbl_a` t0 join `auto_test_remote`.`tbl_a` t1 group by `f2` order by min(t1.`a`),max(t1.`a`),`f2`
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE 'select %'
|
||||
set global log_output=@old_log_output;
|
||||
set global general_log=@old_general_log;
|
||||
DROP DATABASE IF EXISTS auto_test_remote;
|
||||
for master_1
|
||||
for child2
|
||||
|
|
|
@ -44,7 +44,7 @@ connection child2_1;
|
|||
SET NAMES utf8;
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %';
|
||||
argument
|
||||
select t0.`pkey` `pkey`,(left(t0.`txt_utf8` , 4)) `LEFT(``txt_utf8``, 4)` from `auto_test_remote`.`tbl_a` t0 order by `LEFT(``txt_utf8``, 4)` limit 3
|
||||
select t0.`pkey` `pkey`,(left(t0.`txt_utf8` , 4)) `LEFT(``txt_utf8``, 4)` from `auto_test_remote`.`tbl_a` t0 order by (left(`txt_utf8` , 4)) limit 3
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
|
||||
SELECT pkey, txt_utf8 FROM tbl_a ORDER BY pkey;
|
||||
pkey txt_utf8
|
||||
|
|
63
storage/spider/mysql-test/spider/bugfix/t/mdev_26345.test
Normal file
63
storage/spider/mysql-test/spider/bugfix/t/mdev_26345.test
Normal file
|
@ -0,0 +1,63 @@
|
|||
--disable_warnings
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--source ../../t/test_init.inc
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
--enable_warnings
|
||||
|
||||
--echo
|
||||
--echo MDEV-26345 SELECT MIN on Spider table returns more rows than expected
|
||||
--echo
|
||||
|
||||
set spider_same_server_link= 1;
|
||||
evalp CREATE SERVER srv FOREIGN DATA WRAPPER mysql
|
||||
OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root');
|
||||
|
||||
# Case 1: implicit grouping: the const item is SELECTed, but its
|
||||
# results discarded when storing to the temp table
|
||||
create table t2 (a int, b int, PRIMARY KEY (a, b));
|
||||
create table t1 (a int, b int, PRIMARY KEY (a, b)) ENGINE=Spider
|
||||
COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
|
||||
insert into t1 VALUES (1,4), (1,2), (2,11);
|
||||
SELECT MIN(b), a FROM t1 WHERE a=1;
|
||||
SELECT MAX(b), a FROM t1 WHERE a<3;
|
||||
drop table t1, t2;
|
||||
|
||||
# Case 2: implicit grouping: the const item is SELECTed, but its
|
||||
# results discarded when storing to the temp table
|
||||
create table t2 (a int, b int, c int, PRIMARY KEY (a, b));
|
||||
create table t1 (a int, b int, c int, PRIMARY KEY (a, b)) ENGINE=Spider
|
||||
COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
|
||||
insert into t2 VALUES (1,4,1), (1,2,2), (2,11,3);
|
||||
SELECT MIN(b), a, c FROM t1 WHERE a=1;
|
||||
drop table t1, t2;
|
||||
|
||||
# Case 3: auxiliary fields should not be SELECTed
|
||||
create table t2 (a int, b int);
|
||||
create table t1 ENGINE=Spider
|
||||
COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
|
||||
insert into t1 VALUES (1,1), (1,1), (2,2), (2,2);
|
||||
# b is an auxiliary field item. If it was SELECTed, two rows would
|
||||
# return instead of one.
|
||||
select distinct count(a) from t1 group by b;
|
||||
drop table t1, t2;
|
||||
|
||||
# Case 4: having should still work, despite referring to auxiliary
|
||||
# field items which are not SELECTed
|
||||
create table t2 (c int);
|
||||
create table t1 (c int) ENGINE=Spider
|
||||
COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"';
|
||||
insert into t1 values (1),(3),(5),(7),(9),(11),(13),(15);
|
||||
select count(c) as d from t1 having d > 5;
|
||||
drop table t1, t2;
|
||||
|
||||
drop server srv;
|
||||
|
||||
--disable_warnings
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--source ../../t/test_deinit.inc
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
--enable_warnings
|
|
@ -17,6 +17,11 @@ eval CREATE TABLE tbl_a (
|
|||
) $CHILD2_1_ENGINE $CHILD2_1_CHARSET;
|
||||
INSERT INTO tbl_a VALUES (1,2),(3,4);
|
||||
|
||||
set @old_general_log=@@global.general_log;
|
||||
set global general_log=1;
|
||||
set @old_log_output=@@global.log_output;
|
||||
set global log_output="TABLE";
|
||||
|
||||
--connection master_1
|
||||
CREATE DATABASE auto_test_local;
|
||||
USE auto_test_local;
|
||||
|
@ -25,11 +30,19 @@ eval CREATE TABLE tbl_a (
|
|||
b INT
|
||||
) $MASTER_1_ENGINE $MASTER_1_CHARSET COMMENT='table "tbl_a", srv "s_2_1"';
|
||||
|
||||
--disable_ps2_protocol
|
||||
SELECT MIN(t2.a) AS f1, t1.b AS f2 FROM tbl_a AS t1 JOIN tbl_a AS t2 GROUP BY f2 ORDER BY f1, f2;
|
||||
SELECT MIN(t2.a) AS f1, t1.b AS f2 FROM tbl_a AS t1 JOIN tbl_a AS t2 GROUP BY f2 ORDER BY MIN(t2.a), MAX(t2.a), f2;
|
||||
--enable_ps2_protocol
|
||||
|
||||
--connection master_1
|
||||
DROP DATABASE IF EXISTS auto_test_local;
|
||||
--connection child2_1
|
||||
--disable_ps2_protocol
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE 'select %';
|
||||
--enable_ps2_protocol
|
||||
set global log_output=@old_log_output;
|
||||
set global general_log=@old_general_log;
|
||||
DROP DATABASE IF EXISTS auto_test_remote;
|
||||
|
||||
--disable_query_log
|
||||
|
|
|
@ -76,7 +76,7 @@ a b c
|
|||
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 join `auto_test_remote`.`ta_r_3` t1 join `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 t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r` t0 join `auto_test_remote`.`ta_r_3` t1 join `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')
|
||||
|
|
|
@ -79,7 +79,7 @@ a b c
|
|||
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 join `auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r_int` t2 where ((t0.`a` = t1.`a`) and (t2.`a` = t1.`a`)) order by t0.`b` desc
|
||||
select t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r` t0 join `auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r_int` t2 where ((t0.`a` = t1.`a`) and (t2.`a` = t1.`a`)) order by t0.`b` desc
|
||||
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')
|
||||
|
|
|
@ -79,7 +79,7 @@ a b c
|
|||
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 left join `auto_test_remote`.`ta_r_3` t1 on (t1.`a` = t0.`a`) left join `auto_test_remote`.`ta_r_int` t2 on (t2.`a` = t0.`a`) where 1 order by t0.`b` desc
|
||||
select t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r` t0 left join `auto_test_remote`.`ta_r_3` t1 on (t1.`a` = t0.`a`) left join `auto_test_remote`.`ta_r_int` t2 on (t2.`a` = t0.`a`) where 1 order by t0.`b` desc
|
||||
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')
|
||||
|
|
|
@ -79,7 +79,7 @@ a b c
|
|||
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_int` t2 left join (`auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r` t0) on ((t0.`a` = t2.`a`) and (t1.`a` = t2.`a`)) where 1 order by t0.`b` desc
|
||||
select t0.`a` `a`,t2.`b` `b`,t2.`c` `c` from `auto_test_remote`.`ta_r_int` t2 left join (`auto_test_remote`.`ta_r_3` t1 join `auto_test_remote`.`ta_r` t0) on ((t0.`a` = t2.`a`) and (t1.`a` = t2.`a`)) where 1 order by t0.`b` desc
|
||||
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')
|
||||
|
|
|
@ -396,7 +396,7 @@ select t0.`col_d` `col_d`,t0.`col_t` `col_t` from `ts_test_remote`.`tbl_f` t0
|
|||
select (timestamp(t0.`col_d` , t0.`col_t`)) `TIMESTAMP(col_d, col_t)` from `ts_test_remote`.`tbl_f` t0
|
||||
select (timestamp('2018-06-25' , t0.`col_t`)) `TIMESTAMP('2018-06-25', col_t)` from `ts_test_remote`.`tbl_f` t0
|
||||
select (timestamp(t0.`col_d` , '10:43:21')) `TIMESTAMP(col_d, '10:43:21')` from `ts_test_remote`.`tbl_f` t0
|
||||
select 1 from `ts_test_remote`.`tbl_f` t0
|
||||
select (timestamp('2018-06-25' , '10:43:21')) `TIMESTAMP('2018-06-25', '10:43:21')` from `ts_test_remote`.`tbl_f` t0
|
||||
SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'
|
||||
SELECT col_d, col_t FROM tbl_f;
|
||||
col_d col_t
|
||||
|
|
|
@ -2827,6 +2827,7 @@ int spider_db_get_row_from_tmp_tbl_pos(
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/* Store one field result from a given row to a given table field. */
|
||||
int spider_db_fetch_row(
|
||||
SPIDER_SHARE *share,
|
||||
Field *field,
|
||||
|
@ -2851,6 +2852,10 @@ int spider_db_fetch_row(
|
|||
DBUG_RETURN(error_num);
|
||||
}
|
||||
|
||||
/*
|
||||
Retrieve a result row and store the results from the row into the
|
||||
given table
|
||||
*/
|
||||
int spider_db_fetch_table(
|
||||
ha_spider *spider,
|
||||
uchar *buf,
|
||||
|
@ -2863,6 +2868,7 @@ int spider_db_fetch_table(
|
|||
SPIDER_RESULT *current = (SPIDER_RESULT*) result_list->current;
|
||||
SPIDER_DB_ROW *row;
|
||||
Field **field;
|
||||
int n_aux= result_list->n_aux;
|
||||
DBUG_ENTER("spider_db_fetch_table");
|
||||
if (result_list->quick_mode == 0)
|
||||
{
|
||||
|
@ -2940,6 +2946,8 @@ int spider_db_fetch_table(
|
|||
*field;
|
||||
field++
|
||||
) {
|
||||
if (n_aux-- > 0)
|
||||
continue;
|
||||
if ((
|
||||
bitmap_is_set(table->read_set, (*field)->field_index) |
|
||||
bitmap_is_set(table->write_set, (*field)->field_index)
|
||||
|
@ -3788,7 +3796,7 @@ int spider_db_store_result(
|
|||
}
|
||||
current->dbton_id = current->result->dbton_id;
|
||||
SPIDER_DB_ROW *row;
|
||||
if (!(row = current->result->fetch_row()))
|
||||
if (!(row = current->result->fetch_row(result_list->skips)))
|
||||
{
|
||||
error_num = current->result->get_errno();
|
||||
DBUG_PRINT("info",("spider set finish_flg point 3"));
|
||||
|
|
|
@ -801,6 +801,7 @@ public:
|
|||
SPIDER_DB_ROW *next_pos;
|
||||
spider_db_row(uint in_dbton_id) : dbton_id(in_dbton_id), next_pos(NULL) {}
|
||||
virtual ~spider_db_row() = default;
|
||||
/* Store the current field result to a given field */
|
||||
virtual int store_to_field(
|
||||
Field *field,
|
||||
CHARSET_INFO *access_charset
|
||||
|
@ -813,6 +814,7 @@ public:
|
|||
uint dbton_id
|
||||
) = 0;
|
||||
virtual void first() = 0;
|
||||
/* Move to the next field result. */
|
||||
virtual void next() = 0;
|
||||
virtual bool is_null() = 0;
|
||||
virtual int val_int() = 0;
|
||||
|
@ -851,7 +853,7 @@ public:
|
|||
virtual bool has_result() = 0;
|
||||
virtual void free_result() = 0;
|
||||
virtual SPIDER_DB_ROW *current_row() = 0;
|
||||
virtual SPIDER_DB_ROW *fetch_row() = 0;
|
||||
virtual SPIDER_DB_ROW *fetch_row(MY_BITMAP *skips = NULL) = 0;
|
||||
virtual SPIDER_DB_ROW *fetch_row_from_result_buffer(
|
||||
spider_db_result_buffer *spider_res_buf
|
||||
) = 0;
|
||||
|
@ -1549,7 +1551,8 @@ public:
|
|||
uint alias_length,
|
||||
bool use_fields,
|
||||
spider_fields *fields,
|
||||
ulong sql_type
|
||||
ulong sql_type,
|
||||
int n_aux=0
|
||||
) = 0;
|
||||
virtual int append_group_by_part(
|
||||
ORDER *order,
|
||||
|
@ -1838,4 +1841,10 @@ typedef struct st_spider_result_list
|
|||
#endif
|
||||
SPIDER_RESULT *bgs_current;
|
||||
SPIDER_DB_ROW *tmp_pos_row_first;
|
||||
/*
|
||||
A bitmap marking fields to skip when storing results fetched from
|
||||
the data node to a SPIDER_DB_ROW
|
||||
*/
|
||||
MY_BITMAP *skips;
|
||||
int n_aux;
|
||||
} SPIDER_RESULT_LIST;
|
||||
|
|
|
@ -716,7 +716,13 @@ SPIDER_DB_ROW *spider_db_mbase_result::current_row()
|
|||
DBUG_RETURN((SPIDER_DB_ROW *) row.clone());
|
||||
}
|
||||
|
||||
SPIDER_DB_ROW *spider_db_mbase_result::fetch_row()
|
||||
/*
|
||||
Fetch results from the data node and store them in a
|
||||
SPIDER_DB_ROW
|
||||
|
||||
@param skips A bitmap specifying which fields to skip storing
|
||||
*/
|
||||
SPIDER_DB_ROW *spider_db_mbase_result::fetch_row(MY_BITMAP *skips)
|
||||
{
|
||||
DBUG_ENTER("spider_db_mbase_result::fetch_row");
|
||||
DBUG_PRINT("info",("spider this=%p", this));
|
||||
|
@ -732,7 +738,22 @@ SPIDER_DB_ROW *spider_db_mbase_result::fetch_row()
|
|||
DBUG_RETURN(NULL);
|
||||
}
|
||||
row.lengths = mysql_fetch_lengths(db_result);
|
||||
row.field_count = mysql_num_fields(db_result);
|
||||
if (skips != NULL)
|
||||
{
|
||||
uint i= 0;
|
||||
for (uint j= 0; j < mysql_num_fields(db_result); j++)
|
||||
{
|
||||
if (!bitmap_is_set(skips, j))
|
||||
{
|
||||
row.row[i]= row.row[j];
|
||||
row.lengths[i]= row.lengths[j];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
row.field_count= i;
|
||||
}
|
||||
else
|
||||
row.field_count = mysql_num_fields(db_result);
|
||||
row.row[row.field_count] = NULL;
|
||||
row.row_first = row.row;
|
||||
row.lengths_first = row.lengths;
|
||||
|
@ -13944,7 +13965,8 @@ int spider_mbase_handler::append_list_item_select_part(
|
|||
uint alias_length,
|
||||
bool use_fields,
|
||||
spider_fields *fields,
|
||||
ulong sql_type
|
||||
ulong sql_type,
|
||||
int n_aux
|
||||
) {
|
||||
int error_num;
|
||||
spider_string *str;
|
||||
|
@ -13959,7 +13981,7 @@ int spider_mbase_handler::append_list_item_select_part(
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
error_num = append_list_item_select(select, str, alias, alias_length,
|
||||
use_fields, fields);
|
||||
use_fields, fields, n_aux);
|
||||
DBUG_RETURN(error_num);
|
||||
}
|
||||
|
||||
|
@ -13969,38 +13991,29 @@ int spider_mbase_handler::append_list_item_select(
|
|||
const char *alias,
|
||||
uint alias_length,
|
||||
bool use_fields,
|
||||
spider_fields *fields
|
||||
spider_fields *fields,
|
||||
int n_aux
|
||||
) {
|
||||
int error_num;
|
||||
uint32 length, begin;
|
||||
List_iterator_fast<Item> it(*select);
|
||||
Item *item;
|
||||
Field *field;
|
||||
const char *item_name;
|
||||
DBUG_ENTER("spider_mbase_handler::append_list_item_select");
|
||||
DBUG_PRINT("info",("spider this=%p", this));
|
||||
begin = str->length();
|
||||
while ((item = it++))
|
||||
{
|
||||
if (item->const_item())
|
||||
{
|
||||
DBUG_PRINT("info",("spider const item"));
|
||||
fields->get_next_field_ptr();
|
||||
if (n_aux-- > 0)
|
||||
continue;
|
||||
}
|
||||
if ((error_num = spider_db_print_item_type(item, NULL, spider, str,
|
||||
alias, alias_length, dbton_id, use_fields, fields)))
|
||||
{
|
||||
DBUG_RETURN(error_num);
|
||||
}
|
||||
field = *(fields->get_next_field_ptr());
|
||||
if (field)
|
||||
{
|
||||
item_name = SPIDER_field_name_str(field);
|
||||
length = SPIDER_field_name_length(field);
|
||||
} else {
|
||||
item_name = SPIDER_item_name_str(item);
|
||||
length = SPIDER_item_name_length(item);
|
||||
}
|
||||
item_name = SPIDER_item_name_str(item);
|
||||
length = SPIDER_item_name_length(item);
|
||||
if (str->reserve(
|
||||
SPIDER_SQL_COMMA_LEN + /* SPIDER_SQL_NAME_QUOTE_LEN */ 2 +
|
||||
SPIDER_SQL_SPACE_LEN + length
|
||||
|
@ -14071,7 +14084,7 @@ int spider_mbase_handler::append_group_by(
|
|||
str->q_append(SPIDER_SQL_GROUP_STR, SPIDER_SQL_GROUP_LEN);
|
||||
for (; order; order = order->next)
|
||||
{
|
||||
if ((error_num = spider_db_print_item_type((*order->item), NULL, spider,
|
||||
if ((error_num = spider_db_print_item_type(order->item_ptr, NULL, spider,
|
||||
str, alias, alias_length, dbton_id, use_fields, fields)))
|
||||
{
|
||||
DBUG_RETURN(error_num);
|
||||
|
@ -14128,7 +14141,7 @@ int spider_mbase_handler::append_order_by(
|
|||
str->q_append(SPIDER_SQL_ORDER_STR, SPIDER_SQL_ORDER_LEN);
|
||||
for (; order; order = order->next)
|
||||
{
|
||||
if ((error_num = spider_db_print_item_type((*order->item), NULL, spider,
|
||||
if ((error_num = spider_db_print_item_type(order->item_ptr, NULL, spider,
|
||||
str, alias, alias_length, dbton_id, use_fields, fields)))
|
||||
{
|
||||
DBUG_RETURN(error_num);
|
||||
|
|
|
@ -294,7 +294,7 @@ public:
|
|||
bool has_result() override;
|
||||
void free_result() override;
|
||||
SPIDER_DB_ROW *current_row() override;
|
||||
SPIDER_DB_ROW *fetch_row() override;
|
||||
SPIDER_DB_ROW *fetch_row(MY_BITMAP *) override;
|
||||
SPIDER_DB_ROW *fetch_row_from_result_buffer(
|
||||
spider_db_result_buffer *spider_res_buf
|
||||
) override;
|
||||
|
@ -1493,7 +1493,8 @@ public:
|
|||
uint alias_length,
|
||||
bool use_fields,
|
||||
spider_fields *fields,
|
||||
ulong sql_type
|
||||
ulong sql_type,
|
||||
int n_aux=0
|
||||
) override;
|
||||
int append_list_item_select(
|
||||
List<Item> *select,
|
||||
|
@ -1501,7 +1502,8 @@ public:
|
|||
const char *alias,
|
||||
uint alias_length,
|
||||
bool use_fields,
|
||||
spider_fields *fields
|
||||
spider_fields *fields,
|
||||
int n_aux
|
||||
);
|
||||
int append_group_by_part(
|
||||
ORDER *order,
|
||||
|
|
|
@ -978,13 +978,16 @@ int spider_fields::ping_table_mon_from_table(
|
|||
spider_group_by_handler::spider_group_by_handler(
|
||||
THD *thd_arg,
|
||||
Query *query_arg,
|
||||
spider_fields *fields_arg
|
||||
spider_fields *fields_arg,
|
||||
const MY_BITMAP &skips1
|
||||
) : group_by_handler(thd_arg, spider_hton_ptr),
|
||||
query(*query_arg), fields(fields_arg)
|
||||
{
|
||||
DBUG_ENTER("spider_group_by_handler::spider_group_by_handler");
|
||||
spider = fields->get_first_table_holder()->spider;
|
||||
trx = spider->wide_handler->trx;
|
||||
my_bitmap_init(&skips, NULL, skips1.n_bits, TRUE);
|
||||
bitmap_copy(&skips, &skips1);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@ -993,11 +996,18 @@ spider_group_by_handler::~spider_group_by_handler()
|
|||
DBUG_ENTER("spider_group_by_handler::~spider_group_by_handler");
|
||||
spider_free(spider_current_trx, fields->get_first_table_holder(), MYF(0));
|
||||
delete fields;
|
||||
my_bitmap_free(&skips);
|
||||
/*
|
||||
The `skips' bitmap may have been copied to the result_list field
|
||||
of the same name
|
||||
*/
|
||||
spider->result_list.skips= NULL;
|
||||
spider->result_list.n_aux= 0;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
static int spider_prepare_init_scan(
|
||||
const Query& query, spider_fields *fields, ha_spider *spider,
|
||||
const Query& query, MY_BITMAP *skips, spider_fields *fields, ha_spider *spider,
|
||||
SPIDER_TRX *trx, longlong& offset_limit, THD *thd)
|
||||
{
|
||||
int error_num, link_idx;
|
||||
|
@ -1072,6 +1082,8 @@ static int spider_prepare_init_scan(
|
|||
result_list->limit_num =
|
||||
result_list->internal_limit >= result_list->split_read ?
|
||||
result_list->split_read : result_list->internal_limit;
|
||||
result_list->skips= skips;
|
||||
result_list->n_aux= query.n_aux;
|
||||
|
||||
if (select_lex->explicit_limit)
|
||||
{
|
||||
|
@ -1101,7 +1113,8 @@ static int spider_make_query(const Query& query, spider_fields* fields, ha_spide
|
|||
DBUG_RETURN(error_num);
|
||||
fields->set_field_ptr(table->field);
|
||||
if ((error_num = dbton_hdl->append_list_item_select_part(
|
||||
query.select, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL)))
|
||||
query.select, NULL, 0, TRUE, fields, SPIDER_SQL_TYPE_SELECT_SQL,
|
||||
query.n_aux)))
|
||||
DBUG_RETURN(error_num);
|
||||
if ((error_num = dbton_hdl->append_from_and_tables_part(
|
||||
fields, SPIDER_SQL_TYPE_SELECT_SQL)))
|
||||
|
@ -1276,7 +1289,7 @@ int spider_group_by_handler::init_scan()
|
|||
}
|
||||
|
||||
if ((error_num = spider_prepare_init_scan(
|
||||
query, fields, spider, trx, offset_limit, thd)))
|
||||
query, &skips, fields, spider, trx, offset_limit, thd)))
|
||||
DBUG_RETURN(error_num);
|
||||
|
||||
if ((error_num = spider_make_query(query, fields, spider, table)))
|
||||
|
@ -1397,6 +1410,7 @@ group_by_handler *spider_create_group_by_handler(
|
|||
SPIDER_TABLE_HOLDER *table_holder;
|
||||
uint table_idx, dbton_id, table_count= 0;
|
||||
long tgt_link_status;
|
||||
MY_BITMAP skips;
|
||||
DBUG_ENTER("spider_create_group_by_handler");
|
||||
|
||||
switch (thd_sql_command(thd))
|
||||
|
@ -1543,13 +1557,30 @@ group_by_handler *spider_create_group_by_handler(
|
|||
fields_arg->set_table_holder(table_holder, table_count);
|
||||
keep_going = TRUE;
|
||||
it.init(*query->select);
|
||||
my_bitmap_init(&skips, NULL, query->select->elements, TRUE);
|
||||
int i= -1, n_aux= query->n_aux;
|
||||
while ((item = it++))
|
||||
{
|
||||
i++;
|
||||
n_aux--;
|
||||
DBUG_PRINT("info",("spider select item=%p", item));
|
||||
if (item->const_item())
|
||||
{
|
||||
DBUG_PRINT("info",("spider const item"));
|
||||
continue;
|
||||
/*
|
||||
Do not handle the complex case where there's a const item
|
||||
in the auxiliary fields. It is too unlikely (if at all) to
|
||||
happen to be covered by the GBH.
|
||||
|
||||
TODO: find an example covering this case or determine it
|
||||
never happens and remove this consideration.
|
||||
*/
|
||||
if (n_aux >= 0)
|
||||
{
|
||||
spider_clear_bit(dbton_bitmap, roop_count);
|
||||
keep_going= FALSE;
|
||||
break;
|
||||
}
|
||||
bitmap_set_bit(&skips, i);
|
||||
}
|
||||
if (spider_db_print_item_type(item, NULL, spider, NULL, NULL, 0,
|
||||
roop_count, TRUE, fields_arg))
|
||||
|
@ -1823,11 +1854,12 @@ group_by_handler *spider_create_group_by_handler(
|
|||
|
||||
fields->set_first_link_idx();
|
||||
|
||||
if (!(group_by_handler = new spider_group_by_handler(thd, query, fields)))
|
||||
if (!(group_by_handler = new spider_group_by_handler(thd, query, fields, skips)))
|
||||
{
|
||||
DBUG_PRINT("info",("spider can't create group_by_handler"));
|
||||
goto skip_free_fields;
|
||||
}
|
||||
my_bitmap_free(&skips);
|
||||
query->distinct = FALSE;
|
||||
query->where = NULL;
|
||||
query->group_by = NULL;
|
||||
|
@ -1839,5 +1871,6 @@ skip_free_fields:
|
|||
delete fields;
|
||||
skip_free_table_holder:
|
||||
spider_free(spider_current_trx, table_holder, MYF(0));
|
||||
my_bitmap_free(&skips);
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
|
|
@ -23,12 +23,20 @@ class spider_group_by_handler: public group_by_handler
|
|||
bool first;
|
||||
longlong offset_limit;
|
||||
int store_error;
|
||||
/*
|
||||
Bitmap marking constant items among the select items. They are
|
||||
SELECTed in the query executed at the data node, but not stored in
|
||||
SPIDER_DB_ROW, because the temp table do not contain the
|
||||
corresponding fields.
|
||||
*/
|
||||
MY_BITMAP skips;
|
||||
|
||||
public:
|
||||
spider_group_by_handler(
|
||||
THD *thd_arg,
|
||||
Query *query_arg,
|
||||
spider_fields *fields_arg
|
||||
spider_fields *fields_arg,
|
||||
const MY_BITMAP &skips1
|
||||
);
|
||||
~spider_group_by_handler();
|
||||
int init_scan() override;
|
||||
|
|
Loading…
Add table
Reference in a new issue