MDEV-39226: Push whole multi-table update/delete down into engines - #5529
MDEV-39226: Push whole multi-table update/delete down into engines#5529bsrikanth-mariadb wants to merge 1 commit into
Conversation
f2ce815 to
44765e4
Compare
| const char *pushed_select_text= "PUSHED SELECT"; | ||
| const char *pushed_update_text= "PUSHED DOWN UPDATE"; | ||
| const char *pushed_delete_text= "PUSHED DOWN DELETE"; | ||
|
|
There was a problem hiding this comment.
Please follow the pattern: if we use PUSHED SELECT, let's add PUSHED UPDATE , not PUSHED DOWN UPDATE.
There was a problem hiding this comment.
Yeah, true. But, felt "PUSHED DOWN XXXX" was sounding better.
Anyways, will keep them consistent.
b931524 to
eb052c3
Compare
7f1147b to
168a3b1
Compare
Give storage engines a way to take over an entire multi-table UPDATE/DELETE, the way they can already take over a SELECT. Without it the join, the row matching and every modification run in the SQL layer even when an engine could do the whole statement itself in one step; a single-table UPDATE/DELETE already avoids this via direct_update_rows()/direct_delete_rows(), but a multi-table statement has no primary handler object to drive that path. This adds a generic, engine-agnostic pushdown interface: the SQL layer offers the statement to the engine, and if the engine accepts it, it performs the whole thing and reports only the row counts. - Split select_handler into a pushdown_handler base with select_handler (result set) and a new multi_upddel_handler (runs a whole UPDATE/DELETE, reports row counts, reported as PUSHED UPDATE/PUSHED DELETE); add handlerton::create_multi_upddel, looked up in Sql_cmd_dml::execute_inner(). - multi_update/multi_delete gain direct_update_delete_done(), which records the engine's counts so send_eof() binlogs and replies without the SQL-layer loop; it forces statement-format binlogging so the change still replicates under binlog_format=ROW, and errors out instead of silently dropping counts for an unsupported result object. - FederatedX implements the interface as the reference engine used to test correctness: it prints the statement back and runs it remotely, passes the engine's error code/SQLSTATE through, reads the matched count from the remote info string, executes IGNORE locally, and only pushes down when all tables share one remote server (same as SELECT/derived/unit pushdown). Test: federated.federatedx_pushdown_upd_del.
168a3b1 to
f59b0bd
Compare
| static multi_upddel_handler * | ||
| create_federatedx_multi_upddel_handler(THD *thd, SELECT_LEX *sel_lex) | ||
| { | ||
| if (!use_pushdown || !is_supported_update_delete(thd->lex->sql_command)) |
There was a problem hiding this comment.
What is this for? Do we get into this function for non-UPDATE/DELETE ?
I have added
DBUG_ASSERT(is_supported_update_delete(thd->lex->sql_command));
and it survived the tests.
|
Please apply this patch: cleanups.patch |
| str_eq(a->hostname, b->hostname) && | ||
| str_eq(a->socket, b->socket) && | ||
| str_eq(a->username, b->username) && | ||
| str_eq(a->password, b->password); |
There was a problem hiding this comment.
Even password?
I'm not sure if it's possible to see different data depending on the user... Is password necessary?
|
|
||
| ha_federatedx_multi_upddel_handler::~ha_federatedx_multi_upddel_handler() | ||
| = default; | ||
|
|
| The range of the error codes of the client library, CR_MIN_ERROR and | ||
| CR_MAX_ERROR of errmsg.h. That header cannot be included here because it | ||
| defines ER, which the server defines differently. | ||
| */ |
There was a problem hiding this comment.
If ER is the only problem, can one use
#undef ER
#include ...
?
spetrunia
left a comment
There was a problem hiding this comment.
See above input.
Also, should create_multi_upddel accept SELECT_LEX argument, or LEX would be more meaningful?
Give storage engines a way to take over an entire multi-table
UPDATE/DELETE, the way they can already take over a SELECT. Without it the
join, the row matching and every modification run in the SQL layer even
when an engine could do the whole statement itself in one step; a
single-table UPDATE/DELETE already avoids this via
direct_update_rows()/direct_delete_rows(), but a multi-table statement has
no primary handler object to drive that path.
This adds a generic, engine-agnostic pushdown interface: the SQL layer
offers the statement to the engine, and if the engine accepts it, it
performs the whole thing and reports only the row counts.
(result set) and a new multi_upddel_handler (runs a whole UPDATE/DELETE,
reports row counts, reported as PUSHED UPDATE/PUSHED DELETE); add
handlerton::create_multi_upddel, looked up in Sql_cmd_dml::execute_inner().
the engine's counts so send_eof() binlogs and replies without the
SQL-layer loop; it forces statement-format binlogging so the change still
replicates under binlog_format=ROW, and errors out instead of silently
dropping counts for an unsupported result object.
correctness: it prints the statement back and runs it remotely, passes
the engine's error code/SQLSTATE through, reads the matched count from the
remote info string, executes IGNORE locally, and only pushes down when all
tables share one remote server (same as SELECT/derived/unit pushdown).
Test: federated.federatedx_pushdown_upd_del.