1
0
mirror of https://github.com/MariaDB/server.git synced 2026-10-23 18:49:29 +03:00

MDEV-37484: Sql_cmd_dml::execute_inner, Sql_cmd_update::execute_inner do not call Select handler for the engine involved

Problem:
  After the re-design of `UPDATE` and `DELETE` in MDEV-28883, the call
  to find select handler is missing. This prevents the server from
  handring over multi-update/multi-delete queries to storage engines
  capable of executng such queries on their own (e.g., ColumnStore).

  MDEV-32382 introduced a check in `find_select_handler_inner` function,
  that blocked pushdown of queries involving CTEs, without checking if
  the storage engine is capable of handling such queries.

Fix:
  Add a call to find the select handler for the engine involved in the
  multi-update/multi-delete query, allowing the storage engines to
  execute such queries.

  Fix the `find_select_handler_inner` function by allowing the storage
  engine's create_select functions to decide the pushdown of queries
  involving CTEs.
This commit is contained in:
Raghunandan Bhat
2025-10-13 17:13:35 +05:30
committed by Raghunandan Bhat
parent a61a746f08
commit dcf59cc248
7 changed files with 592 additions and 9 deletions

View File

@@ -1350,6 +1350,229 @@ federated.t12, federated.t13, federated.t14;
connection slave;
DROP TABLES federated.t1, federated.t2, federated.t11, federated.t12,
federated.t13, federated.t14;
#
# MDEV-37484: `Sql_cmd_dml::execute_inner`, `Sql_cmd_update::execute_inner` do not call Select handler for the engine involved
#
connection default;
set global federated_pushdown=1;
connection slave;
create table federated.product_tag (product_id bigint);
CREATE TABLE federated.product (
`product_id` bigint(20) DEFAULT NULL,
`price` bigint(20) DEFAULT NULL,
`short_description` varchar(7998) DEFAULT NULL,
`brand` varchar(254) DEFAULT NULL,
`modified_dtm` datetime DEFAULT NULL,
`created_dtm` datetime DEFAULT NULL,
`modified_by` int(11) DEFAULT NULL
) CHARSET=latin1;
connection master;
create table federated.product_tag (product_id bigint)
ENGINE="FEDERATED"
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/product_tag';
CREATE TABLE federated.product (
`product_id` bigint(20) DEFAULT NULL,
`price` bigint(20) DEFAULT NULL,
`short_description` varchar(7998) DEFAULT NULL,
`brand` varchar(254) DEFAULT NULL,
`modified_dtm` datetime DEFAULT NULL,
`created_dtm` datetime DEFAULT NULL,
`modified_by` int(11) DEFAULT NULL
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/product';
insert into federated.product_tag values (1),(2),(3),(4);
insert into federated.product values (1,22,'fes','rets','2011-12-12 12:12:12','2011-12-13 1:1:10',343);
insert into federated.product values (3,22,'fes','rets','2011-12-12 12:12:12','2011-12-13 1:1:10',343);
select * from federated.product order by product_id;
product_id price short_description brand modified_dtm created_dtm modified_by
1 22 fes rets 2011-12-12 12:12:12 2011-12-13 01:01:10 343
3 22 fes rets 2011-12-12 12:12:12 2011-12-13 01:01:10 343
explain format=json update
federated.product p join
(select product_id from federated.product_tag limit 1000) t using (product_id)
set brand=p.product_id, price=555, modified_dtm='2011-12-15 15:15:30',
short_description=concat(short_description,modified_by);
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 1000.010933,
"nested_loop": [
{
"table": {
"table_name": "p",
"access_type": "ALL",
"loops": 1,
"rows": 2,
"cost": 1000.010388,
"filtered": 100,
"attached_condition": "p.product_id is not null"
}
},
{
"table": {
"table_name": "<derived2>",
"access_type": "ref",
"possible_keys": ["key0"],
"key": "key0",
"key_length": "9",
"used_key_parts": ["product_id"],
"ref": ["federated.p.product_id"],
"loops": 2,
"rows": 1,
"cost": 0.000545388,
"filtered": 100,
"materialized": {
"query_block": {
"select_id": 2,
"table": {
"message": "Pushed derived"
}
}
}
}
}
]
}
}
update
federated.product p join
(select product_id from federated.product_tag limit 1000) t using (product_id)
set brand=p.product_id, price=555, modified_dtm='2011-12-15 15:15:30',
short_description=concat(short_description,modified_by);
select * from federated.product order by product_id;
product_id price short_description brand modified_dtm created_dtm modified_by
1 555 fes343 1 2011-12-15 15:15:30 2011-12-13 01:01:10 343
3 555 fes343 3 2011-12-15 15:15:30 2011-12-13 01:01:10 343
drop table federated.product_tag;
drop table federated.product;
connection slave;
drop table federated.product_tag;
drop table federated.product;
# Setup
create or replace table federated.t1 (id int);
create or replace table federated.t2 (id int, op varchar(10), op_count int DEFAULT 0) CHARSET=latin1;
connection master;
create or replace table federated.t1 (id int)
ENGINE="FEDERATED"
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
create or replace table federated.t2 (id int, op varchar(10), op_count int DEFAULT 0)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t2';
insert into federated.t1 values (1),(2),(3),(4);
insert into federated.t2 (id, op) values (1, 'inserted'), (2, 'inserted'), (3, 'inserted'), (4, 'inserted');
select * from federated.t2 order by id;
id op op_count
1 inserted 0
2 inserted 0
3 inserted 0
4 inserted 0
# Update tests
explain format=json update federated.t2 inner join federated.t1 on t2.id = t1.id
set t2.op = 'updated', t2.op_count = t2.op_count + 1
where t2.id in (1, 2);
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 2000.022975,
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"loops": 1,
"rows": 4,
"cost": 1000.010655,
"filtered": 100,
"attached_condition": "t2.`id` in (1,2)"
}
},
{
"table": {
"table_name": "t1",
"access_type": "ALL",
"loops": 4,
"rows": 4,
"cost": 1000.012319,
"filtered": 100,
"attached_condition": "t1.`id` = t2.`id`"
}
}
]
}
}
update federated.t2 inner join federated.t1 on t2.id = t1.id
set t2.op = 'updated', t2.op_count = t2.op_count + 1
where t2.id in (1, 2);
select * from federated.t2 order by id;
id op op_count
1 updated 1
2 updated 1
3 inserted 0
4 inserted 0
# Prepared update stmt
PREPARE stmt_update FROM
'update federated.t2 inner join federated.t1 on t2.id = t1.id set t2.op_count = t2.op_count + 1, t2.op="updated" where t2.id in (1, 2)';
EXECUTE stmt_update;
DEALLOCATE PREPARE stmt_update;
select * from federated.t2 order by id;
id op op_count
1 updated 2
2 updated 2
3 inserted 0
4 inserted 0
# Delete tests
explain format=json
delete federated.t2 from federated.t2 inner join federated.t1 on t2.id = t1.id and t2.op = 'updated';
EXPLAIN
{
"query_block": {
"select_id": 1,
"cost": 2000.023025,
"nested_loop": [
{
"table": {
"table_name": "t2",
"access_type": "ALL",
"loops": 1,
"rows": 4,
"cost": 1000.010705,
"filtered": 100,
"attached_condition": "t2.op = 'updated'"
}
},
{
"table": {
"table_name": "t1",
"access_type": "ALL",
"loops": 4,
"rows": 4,
"cost": 1000.012319,
"filtered": 100,
"attached_condition": "t1.`id` = t2.`id`"
}
}
]
}
}
delete federated.t2 from federated.t2 inner join federated.t1 on t2.id = t1.id and t2.op = 'updated';
select * from federated.t2 order by id;
id op op_count
3 inserted 0
4 inserted 0
# Prepared delete stmt
PREPARE stmt_delete FROM
'delete federated.t2 from federated.t2 inner join federated.t1 on t2.id = t1.id where t2.id = 3';
EXECUTE stmt_delete;
DEALLOCATE PREPARE stmt_delete;
select * from federated.t2 order by id;
id op op_count
4 inserted 0
drop table federated.t1, federated.t2;
connection slave;
drop table federated.t1, federated.t2;
connection default;
set global federated_pushdown=0;
connection master;
@@ -1358,3 +1581,4 @@ DROP DATABASE IF EXISTS federated;
connection slave;
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
# End of 11.4 tests

View File

@@ -895,9 +895,133 @@ connection slave;
DROP TABLES federated.t1, federated.t2, federated.t11, federated.t12,
federated.t13, federated.t14;
--echo #
--echo # MDEV-37484: `Sql_cmd_dml::execute_inner`, `Sql_cmd_update::execute_inner` do not call Select handler for the engine involved
--echo #
connection default;
set global federated_pushdown=1;
connection slave;
create table federated.product_tag (product_id bigint);
CREATE TABLE federated.product (
`product_id` bigint(20) DEFAULT NULL,
`price` bigint(20) DEFAULT NULL,
`short_description` varchar(7998) DEFAULT NULL,
`brand` varchar(254) DEFAULT NULL,
`modified_dtm` datetime DEFAULT NULL,
`created_dtm` datetime DEFAULT NULL,
`modified_by` int(11) DEFAULT NULL
) CHARSET=latin1;
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval
create table federated.product_tag (product_id bigint)
ENGINE="FEDERATED"
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/product_tag';
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval
CREATE TABLE federated.product (
`product_id` bigint(20) DEFAULT NULL,
`price` bigint(20) DEFAULT NULL,
`short_description` varchar(7998) DEFAULT NULL,
`brand` varchar(254) DEFAULT NULL,
`modified_dtm` datetime DEFAULT NULL,
`created_dtm` datetime DEFAULT NULL,
`modified_by` int(11) DEFAULT NULL
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/product';
insert into federated.product_tag values (1),(2),(3),(4);
insert into federated.product values (1,22,'fes','rets','2011-12-12 12:12:12','2011-12-13 1:1:10',343);
insert into federated.product values (3,22,'fes','rets','2011-12-12 12:12:12','2011-12-13 1:1:10',343);
select * from federated.product order by product_id;
let $query=
update
federated.product p join
(select product_id from federated.product_tag limit 1000) t using (product_id)
set brand=p.product_id, price=555, modified_dtm='2011-12-15 15:15:30',
short_description=concat(short_description,modified_by);
eval explain format=json $query;
eval $query;
select * from federated.product order by product_id;
drop table federated.product_tag;
drop table federated.product;
connection slave;
drop table federated.product_tag;
drop table federated.product;
--echo # Setup
create or replace table federated.t1 (id int);
create or replace table federated.t2 (id int, op varchar(10), op_count int DEFAULT 0) CHARSET=latin1;
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval
create or replace table federated.t1 (id int)
ENGINE="FEDERATED"
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval
create or replace table federated.t2 (id int, op varchar(10), op_count int DEFAULT 0)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t2';
insert into federated.t1 values (1),(2),(3),(4);
insert into federated.t2 (id, op) values (1, 'inserted'), (2, 'inserted'), (3, 'inserted'), (4, 'inserted');
select * from federated.t2 order by id;
--echo # Update tests
let $query=
update federated.t2 inner join federated.t1 on t2.id = t1.id
set t2.op = 'updated', t2.op_count = t2.op_count + 1
where t2.id in (1, 2);
eval explain format=json $query;
eval $query;
select * from federated.t2 order by id;
--echo # Prepared update stmt
PREPARE stmt_update FROM
'update federated.t2 inner join federated.t1 on t2.id = t1.id set t2.op_count = t2.op_count + 1, t2.op="updated" where t2.id in (1, 2)';
EXECUTE stmt_update;
DEALLOCATE PREPARE stmt_update;
select * from federated.t2 order by id;
--echo # Delete tests
explain format=json
delete federated.t2 from federated.t2 inner join federated.t1 on t2.id = t1.id and t2.op = 'updated';
delete federated.t2 from federated.t2 inner join federated.t1 on t2.id = t1.id and t2.op = 'updated';
select * from federated.t2 order by id;
--echo # Prepared delete stmt
PREPARE stmt_delete FROM
'delete federated.t2 from federated.t2 inner join federated.t1 on t2.id = t1.id where t2.id = 3';
EXECUTE stmt_delete;
DEALLOCATE PREPARE stmt_delete;
select * from federated.t2 order by id;
drop table federated.t1, federated.t2;
connection slave;
drop table federated.t1, federated.t2;
# cleanup
connection default;
set global federated_pushdown=0;
source include/federated_cleanup.inc;
--echo # End of 11.4 tests

View File

@@ -1622,6 +1622,13 @@ bool Sql_cmd_delete::precheck(THD *thd)
{
if (multi_delete_precheck(thd, lex->query_tables))
return true;
SELECT_LEX *select_lex= lex->first_select_lex();
/* condition will be TRUE on SP re-excuting */
if (select_lex->item_list.elements != 0)
select_lex->item_list.empty();
if (add_item_to_list(thd, new (thd->mem_root) Item_null(thd)))
return true;
}
#ifdef WITH_WSREP

View File

@@ -5218,15 +5218,9 @@ select_handler *find_select_handler_inner(THD *thd,
SELECT_LEX *select_lex,
SELECT_LEX_UNIT *select_lex_unit)
{
if (select_lex->master_unit()->outer_select() ||
(select_lex_unit && select_lex->master_unit()->with_clause))
{
/*
Pushdown is not supported neither for non-top-level SELECTs nor for parts
of SELECT_LEX_UNITs that have CTEs (SELECT_LEX_UNIT::with_clause)
*/
// Pushdown is not supported for non-top-level SELECTs
if (select_lex->master_unit()->outer_select())
return 0;
}
TABLE_LIST *tbl= nullptr;
// For SQLCOM_INSERT_SELECT the server takes TABLE_LIST
@@ -34603,6 +34597,9 @@ bool Sql_cmd_dml::execute_inner(THD *thd)
SELECT_LEX *select_lex= unit->first_select();
JOIN *join= select_lex->join;
// look for select_handler provided by engines
select_lex->pushdown_select= find_single_select_handler(thd, select_lex);
if (join->optimize())
goto err;

View File

@@ -239,6 +239,9 @@ create_federatedx_select_handler(THD *thd, SELECT_LEX *sel_lex,
if (!use_pushdown || !is_supported_by_select_handler(thd->lex->sql_command))
return nullptr;
if (lex_unit && sel_lex->master_unit()->with_clause)
return nullptr;
auto tbl= get_fed_table_for_pushdown(sel_lex);
if (!tbl)
return nullptr;

View File

@@ -0,0 +1,118 @@
#
# MDEV-37484: `Sql_cmd_dml::execute_inner`, `Sql_cmd_update::execute_inner` do not call Select handler for the engine involved
#
for master_1
for child2
for child3
set spider_same_server_link=1;
CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test', user 'root');
create table product_tag(product_id bigint);
create table product (
`product_id` bigint(20) DEFAULT NULL,
`price` bigint(20) DEFAULT NULL,
`short_description` varchar(7998) DEFAULT NULL,
`brand` varchar(254) DEFAULT NULL,
`modified_dtm` datetime DEFAULT NULL,
`created_dtm` datetime DEFAULT NULL,
`modified_by` int(11) DEFAULT NULL
);
insert into product_tag values (1),(2),(3),(4);
insert into product values (1,22,'fes','rets','2011-12-12 12:12:12','2011-12-13 1:1:10',343);
insert into product values (3,22,'fes','rets','2011-12-12 12:12:12','2011-12-13 1:1:10',343);
create table product_tag_spider (product_id bigint) ENGINE=SPIDER REMOTE_SERVER=s REMOTE_TABLE=product_tag;
create table product_spider (
`product_id` bigint(20) DEFAULT NULL,
`price` bigint(20) DEFAULT NULL,
`short_description` varchar(7998) DEFAULT NULL,
`brand` varchar(254) DEFAULT NULL,
`modified_dtm` datetime DEFAULT NULL,
`created_dtm` datetime DEFAULT NULL,
`modified_by` int(11) DEFAULT NULL
) ENGINE=SPIDER REMOTE_SERVER=s REMOTE_TABLE=product;
select * from product_spider order by product_id;
product_id price short_description brand modified_dtm created_dtm modified_by
1 22 fes rets 2011-12-12 12:12:12 2011-12-13 01:01:10 343
3 22 fes rets 2011-12-12 12:12:12 2011-12-13 01:01:10 343
explain update
product_spider p join
(select product_id from product_tag_spider limit 1000) t using (product_id)
set brand=p.product_id, price=555, modified_dtm='2011-12-15 15:15:30',
short_description=concat(short_description,modified_by);
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY p ALL NULL NULL NULL NULL 2 Using where with pushed condition
1 PRIMARY <derived2> ref key0 key0 9 test.p.product_id 1
2 DERIVED product_tag_spider ALL NULL NULL NULL NULL 4
update
product_spider p join
(select product_id from product_tag_spider limit 1000) t using (product_id)
set brand=p.product_id, price=555, modified_dtm='2011-12-15 15:15:30',
short_description=concat(short_description,modified_by);
select * from product_spider order by product_id;
product_id price short_description brand modified_dtm created_dtm modified_by
1 555 fes343 1 2011-12-15 15:15:30 2011-12-13 01:01:10 343
3 555 fes343 3 2011-12-15 15:15:30 2011-12-13 01:01:10 343
drop table product, product_tag, product_spider, product_tag_spider;
create table t1 (id int);
create table t2 (id int, op varchar(10), op_count int DEFAULT 0);
insert into t1 values (1),(2),(3),(4);
insert into t2 (id, op) values (1, 'inserted'), (2, 'inserted'), (3, 'inserted'), (4, 'inserted');
CREATE TABLE t1_SPIDER (id int) ENGINE=SPIDER REMOTE_SERVER=s REMOTE_TABLE=t1;
CREATE TABLE t2_SPIDER (id int, op varchar(10), op_count int DEFAULT 0) ENGINE=SPIDER REMOTE_SERVER=s REMOTE_TABLE=t2;
select * from t2_SPIDER order by id;
id op op_count
1 inserted 0
2 inserted 0
3 inserted 0
4 inserted 0
# Update tests
explain update t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id
set t2_SPIDER.op = 'updated', t2_SPIDER.op_count = t2_SPIDER.op_count + 1
where t2_SPIDER.id in (1, 2);
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2_SPIDER ALL NULL NULL NULL NULL 4 Using where with pushed condition
1 SIMPLE t1_SPIDER ALL NULL NULL NULL NULL 4 Using where
update t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id
set t2_SPIDER.op = 'updated', t2_SPIDER.op_count = t2_SPIDER.op_count + 1
where t2_SPIDER.id in (1, 2);
select * from t2_SPIDER order by id;
id op op_count
1 updated 1
2 updated 1
3 inserted 0
4 inserted 0
PREPARE stmt_update FROM
'update t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id set t2_SPIDER.op_count = t2_SPIDER.op_count + 1, t2_SPIDER.op="updated" where t2_SPIDER.id in (1, 2)';
EXECUTE stmt_update;
DEALLOCATE PREPARE stmt_update;
select * from t2_SPIDER order by id;
id op op_count
1 updated 2
2 updated 2
3 inserted 0
4 inserted 0
# Delete tests
explain
delete t2_SPIDER from t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id and t2_SPIDER.op = 'updated';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2_SPIDER ALL NULL NULL NULL NULL 4 Using where with pushed condition
1 SIMPLE t1_SPIDER ALL NULL NULL NULL NULL 4 Using where
delete t2_SPIDER from t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id and t2_SPIDER.op = 'updated';
select * from t2_SPIDER order by id;
id op op_count
3 inserted 0
4 inserted 0
PREPARE stmt_delete FROM
'delete t2_SPIDER from t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id where t2_SPIDER.id = 3';
EXECUTE stmt_delete;
DEALLOCATE PREPARE stmt_delete;
select * from t2_SPIDER order by id;
id op op_count
4 inserted 0
drop table t1, t2, t1_SPIDER, t2_SPIDER;
drop server s;
for master_1
for child2
for child3
#
# end of test MDEV-37484
#

View File

@@ -0,0 +1,110 @@
--echo #
--echo # MDEV-37484: `Sql_cmd_dml::execute_inner`, `Sql_cmd_update::execute_inner` do not call Select handler for the engine involved
--echo #
--disable_query_log
--disable_result_log
--source ../../t/test_init.inc
--enable_result_log
--enable_query_log
set spider_same_server_link=1;
evalp CREATE SERVER s FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test', user 'root');
create table product_tag(product_id bigint);
create table product (
`product_id` bigint(20) DEFAULT NULL,
`price` bigint(20) DEFAULT NULL,
`short_description` varchar(7998) DEFAULT NULL,
`brand` varchar(254) DEFAULT NULL,
`modified_dtm` datetime DEFAULT NULL,
`created_dtm` datetime DEFAULT NULL,
`modified_by` int(11) DEFAULT NULL
);
insert into product_tag values (1),(2),(3),(4);
insert into product values (1,22,'fes','rets','2011-12-12 12:12:12','2011-12-13 1:1:10',343);
insert into product values (3,22,'fes','rets','2011-12-12 12:12:12','2011-12-13 1:1:10',343);
create table product_tag_spider (product_id bigint) ENGINE=SPIDER REMOTE_SERVER=s REMOTE_TABLE=product_tag;
create table product_spider (
`product_id` bigint(20) DEFAULT NULL,
`price` bigint(20) DEFAULT NULL,
`short_description` varchar(7998) DEFAULT NULL,
`brand` varchar(254) DEFAULT NULL,
`modified_dtm` datetime DEFAULT NULL,
`created_dtm` datetime DEFAULT NULL,
`modified_by` int(11) DEFAULT NULL
) ENGINE=SPIDER REMOTE_SERVER=s REMOTE_TABLE=product;
select * from product_spider order by product_id;
let $query=
update
product_spider p join
(select product_id from product_tag_spider limit 1000) t using (product_id)
set brand=p.product_id, price=555, modified_dtm='2011-12-15 15:15:30',
short_description=concat(short_description,modified_by);
eval explain $query;
eval $query;
select * from product_spider order by product_id;
drop table product, product_tag, product_spider, product_tag_spider;
create table t1 (id int);
create table t2 (id int, op varchar(10), op_count int DEFAULT 0);
insert into t1 values (1),(2),(3),(4);
insert into t2 (id, op) values (1, 'inserted'), (2, 'inserted'), (3, 'inserted'), (4, 'inserted');
CREATE TABLE t1_SPIDER (id int) ENGINE=SPIDER REMOTE_SERVER=s REMOTE_TABLE=t1;
CREATE TABLE t2_SPIDER (id int, op varchar(10), op_count int DEFAULT 0) ENGINE=SPIDER REMOTE_SERVER=s REMOTE_TABLE=t2;
select * from t2_SPIDER order by id;
--echo # Update tests
let $query=
update t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id
set t2_SPIDER.op = 'updated', t2_SPIDER.op_count = t2_SPIDER.op_count + 1
where t2_SPIDER.id in (1, 2);
eval explain $query;
eval $query;
select * from t2_SPIDER order by id;
PREPARE stmt_update FROM
'update t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id set t2_SPIDER.op_count = t2_SPIDER.op_count + 1, t2_SPIDER.op="updated" where t2_SPIDER.id in (1, 2)';
EXECUTE stmt_update;
DEALLOCATE PREPARE stmt_update;
select * from t2_SPIDER order by id;
--echo # Delete tests
explain
delete t2_SPIDER from t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id and t2_SPIDER.op = 'updated';
delete t2_SPIDER from t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id and t2_SPIDER.op = 'updated';
select * from t2_SPIDER order by id;
PREPARE stmt_delete FROM
'delete t2_SPIDER from t2_SPIDER inner join t1_SPIDER on t2_SPIDER.id = t1_SPIDER.id where t2_SPIDER.id = 3';
EXECUTE stmt_delete;
DEALLOCATE PREPARE stmt_delete;
select * from t2_SPIDER order by id;
drop table t1, t2, t1_SPIDER, t2_SPIDER;
drop server s;
--disable_query_log
--disable_result_log
--source ../../t/test_deinit.inc
--enable_result_log
--enable_query_log
--echo #
--echo # end of test MDEV-37484
--echo #