-
Notifications
You must be signed in to change notification settings - Fork 899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Miq expression removes sql only fields for filters #22347
Conversation
6bcbc30
to
5640b59
Compare
a73a19c
to
2dfaac8
Compare
update:
|
2dfaac8
to
57394e3
Compare
57394e3
to
07ed0b8
Compare
Update:
|
07ed0b8
to
0b44ee2
Compare
update:
|
update:
|
0b44ee2
to
161584c
Compare
update:
|
161584c
to
74b09b6
Compare
lib/miq_expression.rb
Outdated
# Inside a NOT, the OR acts like the AND, and the AND acts like the OR | ||
# so swap is introduced to handle Demorgan's law | ||
# | ||
def reduce_exp(exp, mode, swap: false) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is reduce_exp modifying the original exp, or just returning a copy? If the former, can we name it reduce_exp!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
original expression is not changed, but it does point to some of the entries from it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry i'm late to this, but seems like we're dividing/filtering based on the mode (ruby/sql). reduce
makes me think of the ruby enumerable method and that we're just simplifying. Partitioning by mode is what I think this is doing after reviewing the code. It's too bad partition is also an enumerable method. I guess divide is the best I can offer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will rename to prune_exp
. We are pruning out the nodes that are no relevant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Naming-wise, seen
and swap
I find confusing, but I understand why you chose the names. I just know future-me won't understand what those mean. That being said, I can't figure out a better name.
Otherwise, this LGTM and my only questions are really on the comments themselves.
74b09b6
to
940b212
Compare
@jrafanie I will pull out the first commit with comments. |
9fce8e8
to
79170ed
Compare
update:
@jrafanie I removed that comment so it only touches MiqExpression and that one call from Rbac. question Would you feel more comfortable if we introduced |
@jrafanie If you feel more comfortable, we can always have Going forward, I would like to build upon this significantly #22397 (fry really wants to 🔥 I'm ok keeping on Will possibly introduce some backport fun in the future as I plan on converting the |
@Fryguy is now a good time to get this in? |
f0532de
to
36a4f40
Compare
update:
|
36a4f40
to
416bade
Compare
update:
|
416bade
to
1555995
Compare
update:
|
1555995
to
b62ee2b
Compare
update:
|
The goal is to prune nodes from an expression tree that are not applicable to our target language When generating sql, we only want to process nodes that are sql friendly. In the case that both sql and ruby are in and OR clause, we will need to run this in ruby, so both are removed. Logically you can not split up the entries in the OR clause. When generating ruby, we only want to process ruby nodes. Or in the case that both sql and ruby are needed together, we deal with both. This is based upon the original preprocess_for_sql, but it allows flexibility for choosing to keep ruby OR sql. This all came about because in Rbac we are filtering in both sql and ruby. The sql filter was reduced, but the ruby filter contained both the ruby and sql filters. It doesn't make sense to run the same sql filters when processing ruby since those have already been run. In a followup commit, there is a note around demorgan's law which may help you understand a little more about how these various components are splitup
rbac#filter/search can use an miq expression to filter the results. These expressions can be ruby only, sql, or a combination of both. The issue is the code was smart enough to send the sql the WHERE clause that was sql friendly. But when we were filtering in ruby, we performed all the sql filtering and ruby filtering. For 1k records, this takes a hit. After We send the sql only filters to sql and the ruby only filters to ruby. In cases where the OR mixes sql friendly and ruby friendly parameters, we still perform the sql friendly filters in ruby. (logically it is the only way to do it)
Without this change, we were incorrectly filtering records This mostly worked when the ruby expression handled all expressions but it especially breaks down when the two are kept separate
b62ee2b
to
029bc1b
Compare
update:
|
Checked commits kbrock/manageiq@126eeb6~...029bc1b with ruby 2.6.10, rubocop 1.28.2, haml-lint 0.35.0, and yamllint |
Just ran into this today. This will speed up timelines quite a bit. |
LGTM - merging. |
commits:
MiqExpression
.prune_exp
to reduce the expression for a particular mode/language.prune_exp
for sql (waspreprocess_for_sql
)Rbac#filter
now usesprune_exp
to remove unnecessary sql from ruby.!(a || b) == !a && !b
)Dates (via #22358) are on master and were a big win.
Since most of the fields were removed from the ruby expression processing, the whole processing time is approaching the record retrieval timing.
Wish I could have cached
@ruby
as something other thantrue
, but sinceYAML.parse
stores@ruby==nil
as the uninitialized value, I need to store a value other thannil
for a computednil
result.NOTE: the expression was specifically picked because a lot of the fields were sql friendly. less sql friendly expressions will have less gain.