Fix RSQL filter including map attributes - ghost joins and unintended cross joins#3088
Fix RSQL filter including map attributes - ghost joins and unintended cross joins#3088vasilchev wants to merge 1 commit into
Conversation
2857912 to
f493fc0
Compare
Signed-off-by: vasilchev <vasil.ilchev@bosch.com>
f493fc0 to
7127da1
Compare
| return isNot(op) | ||
| ? compare(comparison, toMapValuePath(pathResolver.getJoinOnInner(attribute, split[1]))) | ||
| : cb.and(equal(mapPath.key(), split[1]), compare(comparison, toMapValuePath(mapPath))); | ||
| // map entry with key not null (exist) - use left join per key, key/value filtered in where |
There was a problem hiding this comment.
Isn't there just that "final MapJoin mapPath = (MapJoin) pathResolver.getPath(attribute);" shall not be called if isNot? - it is not used then and just creates additional unused joins?
Wouldn't now lack on be a problem? Causing inefficiciency?
There was a problem hiding this comment.
I've initially tested exactly that and output didn't make any sense - it again creates cross table joins (for each key whole table without any join clause).
if (isNot(op)) {
return compare(comparison, toMapValuePath(pathResolver.getJoinOnInner(attribute, split[1])));
else {
final MapJoin<?, ?, ?> mapPath = (MapJoin<?, ?, ?>) pathResolver.getPath(attribute);
return cb.and(equal(mapPath.key(), split[1]), compare(comparison, toMapValuePath(mapPath)));
}
The only improvement is removing the "ghost" joins that are not used/referenced. But crossjoins (whole table without on clause remains)
attribute.key1=out=(00,01,02) and attribute.key2=out=(03,04,05) and attribute.key3=out=(06,07,08)
SELECT * FROM sp_target_attributes t3, sp_target_attributes t2, sp_target t1, sp_target_attributes t0 WHERE ((((((t3.attribute_value IS NULL) OR NOT ((UPPER(t3.attribute_value) IN (?, ?, ?)))) AND ((t2.attribute_value IS NULL) OR NOT ((UPPER(t2.attribute_value) IN (?, ?, ?))))) AND ((t0.attribute_value IS NULL) OR NOT ((UPPER(t0.attribute_value) IN (?, ?, ?))))) AND (t1.tenant = ?)) AND ((((t3.target = t1.id) AND (UPPER(t3.attribute_key) = ?)) AND ((t2.target = t1.id) AND (UPPER(t2.attribute_key) = ?))) AND ((t0.target = t1.id) AND (UPPER(t0.attribute_key) = ?))))
Problem
RSQL queries filtering targets by map attributes (controller attributes, software module metadata) with multiple AND conditions produce catastrophically large intermediate result sets that cause queries to hang indefinitely in production.
Reported query (attribute.sw_1_version=out=(...) and attribute.sw_2_version=out=(...) and attribute.sw_3_version=out=(...)) generated this SQL:
This affects any map-typed RSQL field: attribute., metadata., or any custom @ElementCollection Map<String,String> field.