diff options
author | Monty <monty@mariadb.org> | 2021-12-27 18:51:00 +0200 |
---|---|---|
committer | Monty <monty@mariadb.org> | 2022-01-05 16:52:39 +0200 |
commit | c18896f9c1ce6e4b9a8519a2d5155698d82ae45a (patch) | |
tree | 38ed69b651bf8ec55bdafd0c424f5a7a493af9f4 /storage/federatedx | |
parent | a48d2ec866751e9da76066bf3a30f99da9031ab0 (diff) | |
download | mariadb-git-c18896f9c1ce6e4b9a8519a2d5155698d82ae45a.tar.gz |
MDEV-14907 FEDERATEDX doesn't respect DISTINCT
Federated and Federatex cannot be used with ROR scans
Federated::position() and Federatex::position() is storing in 'ref' a
pointer into a local result set buffer. This means that one cannot
compare 'ref' from different handler instances to see if they point to the
same physical record.
This bug caused federated.federatedx to return wrong results when the
optimizer tried to use index_merge to resolve some queries.
Fixed by introducing table flag HA_NON_COMPARABLE_ROWID and using this
with the above handlers.
Todo:
- Fix multi_delete(), multi_update and read_records() to use primary key
instead of 'ref' if case HA_NON_COMPARABLE_ROWID is set. The current
code only works if we have only one range (like table scan) for the
tables that will be updated in the second pass.
- Enable DBUG_ASSERT() in ha_federated::cmp_ref() and
ha_federatedx::cmp_ref().
Diffstat (limited to 'storage/federatedx')
-rw-r--r-- | storage/federatedx/ha_federatedx.h | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h index 7b6504db93d..c9d80dd8282 100644 --- a/storage/federatedx/ha_federatedx.h +++ b/storage/federatedx/ha_federatedx.h @@ -338,7 +338,7 @@ public: | HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_CAN_REPAIR | HA_PRIMARY_KEY_REQUIRED_FOR_DELETE | HA_CAN_ONLINE_BACKUPS | - HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY); + HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY | HA_NON_COMPARABLE_ROWID); } /* This is a bitmap of flags that says how the storage engine @@ -428,6 +428,19 @@ public: int rnd_next(uchar *buf); //required int rnd_pos(uchar *buf, uchar *pos); //required void position(const uchar *record); //required + /* + A ref is a pointer inside a local buffer. It is not comparable to + other ref's. This is never called as HA_NON_COMPARABLE_ROWID is set. + */ + int cmp_ref(const uchar *ref1, const uchar *ref2) + { +#ifdef NOT_YET + DBUG_ASSERT(0); + return 0; +#else + return handler::cmp_ref(ref1,ref2); /* Works if table scan is used */ +#endif + } int info(uint); //required int extra(ha_extra_function operation); |