diff --git a/sql/group_by_handler.h b/sql/group_by_handler.h index 5457cb778f5..2a51956f3c1 100644 --- a/sql/group_by_handler.h +++ b/sql/group_by_handler.h @@ -53,6 +53,8 @@ class Select_limit_counters; struct Query { List *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; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fcc1e4dbfea..37ec152141c 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -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}; diff --git a/sql/sql_select.h b/sql/sql_select.h index 49632077ed8..86947fc0bc6 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -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 all_fields; diff --git a/storage/spider/ha_spider.cc b/storage/spider/ha_spider.cc index 25967862c4e..8aff2858c3a 100644 --- a/storage/spider/ha_spider.cc +++ b/storage/spider/ha_spider.cc @@ -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; } diff --git a/storage/spider/ha_spider.h b/storage/spider/ha_spider.h index 6d2e0e40c57..34fad7eee96 100644 --- a/storage/spider/ha_spider.h +++ b/storage/spider/ha_spider.h @@ -910,6 +910,8 @@ public: int append_lock_tables_list(); int lock_tables(); int dml_init(); +private: + void init_fields(); }; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result index e5f16b81329..beea6837bd9 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_20502.result @@ -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; diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_26345.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_26345.result new file mode 100644 index 00000000000..f7d78521472 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_26345.result @@ -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 diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_29008.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_29008.result index 66e33f42a7e..10bf1cc1d9c 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/mdev_29008.result +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_29008.result @@ -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 diff --git a/storage/spider/mysql-test/spider/bugfix/r/select_with_backquote.result b/storage/spider/mysql-test/spider/bugfix/r/select_with_backquote.result index 52f8c98bf98..732446f9fb1 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/select_with_backquote.result +++ b/storage/spider/mysql-test/spider/bugfix/r/select_with_backquote.result @@ -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 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_26345.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_26345.test new file mode 100644 index 00000000000..72069253e84 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_26345.test @@ -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 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_29008.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_29008.test index 28d9a9244e3..f36855d8e71 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/mdev_29008.test +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_29008.test @@ -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 diff --git a/storage/spider/mysql-test/spider/r/direct_join.result b/storage/spider/mysql-test/spider/r/direct_join.result index 5c0f4c808a0..b5511cb8c9c 100644 --- a/storage/spider/mysql-test/spider/r/direct_join.result +++ b/storage/spider/mysql-test/spider/r/direct_join.result @@ -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') diff --git a/storage/spider/mysql-test/spider/r/direct_join_using.result b/storage/spider/mysql-test/spider/r/direct_join_using.result index 93df7b8cd3f..1a4708a739b 100644 --- a/storage/spider/mysql-test/spider/r/direct_join_using.result +++ b/storage/spider/mysql-test/spider/r/direct_join_using.result @@ -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') diff --git a/storage/spider/mysql-test/spider/r/direct_left_join.result b/storage/spider/mysql-test/spider/r/direct_left_join.result index b63f0661b2e..b2149436e03 100644 --- a/storage/spider/mysql-test/spider/r/direct_left_join.result +++ b/storage/spider/mysql-test/spider/r/direct_left_join.result @@ -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') diff --git a/storage/spider/mysql-test/spider/r/direct_right_join.result b/storage/spider/mysql-test/spider/r/direct_right_join.result index b42e40031e3..5504c4b557a 100644 --- a/storage/spider/mysql-test/spider/r/direct_right_join.result +++ b/storage/spider/mysql-test/spider/r/direct_right_join.result @@ -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') diff --git a/storage/spider/mysql-test/spider/r/timestamp.result b/storage/spider/mysql-test/spider/r/timestamp.result index 20e99dc02f8..c7a2a3ebe86 100644 --- a/storage/spider/mysql-test/spider/r/timestamp.result +++ b/storage/spider/mysql-test/spider/r/timestamp.result @@ -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 diff --git a/storage/spider/spd_db_conn.cc b/storage/spider/spd_db_conn.cc index 0d0f1bb2e08..72489a1777e 100644 --- a/storage/spider/spd_db_conn.cc +++ b/storage/spider/spd_db_conn.cc @@ -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")); diff --git a/storage/spider/spd_db_include.h b/storage/spider/spd_db_include.h index eb7875ac056..430cd8479be 100644 --- a/storage/spider/spd_db_include.h +++ b/storage/spider/spd_db_include.h @@ -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; diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 7e10b796f25..92885783daf 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -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 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); diff --git a/storage/spider/spd_db_mysql.h b/storage/spider/spd_db_mysql.h index 028a69e843b..ac00217ff4c 100644 --- a/storage/spider/spd_db_mysql.h +++ b/storage/spider/spd_db_mysql.h @@ -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 *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, diff --git a/storage/spider/spd_group_by_handler.cc b/storage/spider/spd_group_by_handler.cc index 2e4eb003371..f5889edc59e 100644 --- a/storage/spider/spd_group_by_handler.cc +++ b/storage/spider/spd_group_by_handler.cc @@ -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); } diff --git a/storage/spider/spd_group_by_handler.h b/storage/spider/spd_group_by_handler.h index db100de92f2..0583229d4d7 100644 --- a/storage/spider/spd_group_by_handler.h +++ b/storage/spider/spd_group_by_handler.h @@ -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;