summaryrefslogtreecommitdiff
path: root/storage/federatedx
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2021-12-27 18:51:00 +0200
committerMonty <monty@mariadb.org>2022-01-05 16:52:39 +0200
commitc18896f9c1ce6e4b9a8519a2d5155698d82ae45a (patch)
tree38ed69b651bf8ec55bdafd0c424f5a7a493af9f4 /storage/federatedx
parenta48d2ec866751e9da76066bf3a30f99da9031ab0 (diff)
downloadmariadb-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.h15
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);