Skip to content
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

Merged
merged 5 commits into from
May 12, 2023

Conversation

kbrock
Copy link
Member

@kbrock kbrock commented Feb 9, 2023

commits:

  • added some comments around MiqExpression.
  • added prune_exp to reduce the expression for a particular mode/language.
  • using prune_exp for sql (was preprocess_for_sql)
  • Rbac#filter now uses prune_exp to remove unnecessary sql from ruby.
  • fix bugs around Demorgan's law (i.e.: !(a || b) == !a && !b)
code all(ms) records(ms) do_eval(ms) subst(ms) comments
master 2289 815 144 1294
after 1225 769 37 285
delta 46% n/a 74% 78%

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 than true, but since YAML.parse stores @ruby==nil as the uninitialized value, I need to store a value other than nil for a computed nil result.

NOTE: the expression was specifically picked because a lot of the fields were sql friendly. less sql friendly expressions will have less gain.

@kbrock
Copy link
Member Author

kbrock commented Feb 13, 2023

update:

  • working on cops.
  • rearranged nodes to extract 2 PRs (so far)

@kbrock
Copy link
Member Author

kbrock commented Feb 13, 2023

Update:

  • rebased to take in external Count and dependent PR
  • fixed whitespace issues and tweaked demorgan commit to remove duplicate code.

@kbrock
Copy link
Member Author

kbrock commented Feb 13, 2023

update:

  • fixed refactor issue with renaming preprocess_exp!

@kbrock
Copy link
Member Author

kbrock commented Feb 14, 2023

update:

  • added parameter to rbac to turn off prune_sql feature (mostly for performance testing)

@kbrock
Copy link
Member Author

kbrock commented Feb 14, 2023

update:

  • Rbac#filtered takes a parameter to turn on/off the ruby filter

lib/miq_expression.rb Outdated Show resolved Hide resolved
lib/miq_expression.rb Outdated Show resolved Hide resolved
# 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)
Copy link
Member

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!

Copy link
Member Author

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

Copy link
Member

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.

Copy link
Member Author

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

Copy link
Member

@Fryguy Fryguy left a 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.

@kbrock
Copy link
Member Author

kbrock commented Mar 8, 2023

@jrafanie I will pull out the first commit with comments.
They touch a number of files. would be best to have this PR touch as few files as possible

@kbrock
Copy link
Member Author

kbrock commented Mar 9, 2023

update:

  • rebased
  • removed comment commit (down to touching 4 files - 2 code and 2 specs)

@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 to_ruby_only - basically to_ruby but with its own @ruby_only cache?

@jrafanie
Copy link
Member

jrafanie commented Mar 9, 2023

@Fryguy @kbrock what are your thoughts on this? I think it's good but would probably like to merge and not yet backport it to petrosian so we can test it on master for a bit.

@kbrock
Copy link
Member Author

kbrock commented Mar 10, 2023

@jrafanie If you feel more comfortable, we can always have @ruby and @ruby_only. Either as 2 methods or the method using the param to determine the source.

Going forward, I would like to build upon this significantly #22397 (fry really wants to 🔥 eval and I don't blame him)

I'm ok keeping on master only.

Will possibly introduce some backport fun in the future as I plan on converting the get_col_info calls over to Field in reports (core, ui classic controller, and views).

@kbrock
Copy link
Member Author

kbrock commented Mar 22, 2023

@Fryguy is now a good time to get this in?

@kbrock kbrock force-pushed the miq_expression_to_ruby branch 2 times, most recently from f0532de to 36a4f40 Compare March 31, 2023 01:09
@kbrock
Copy link
Member Author

kbrock commented Mar 31, 2023

update:

  • added spec to ensure that to_ruby busted the cache when different arguments were passed in.

@kbrock
Copy link
Member Author

kbrock commented Apr 13, 2023

update:

  • renamed reduce_exp to prune_exp since it prunes the expression according to the desired target (per @jrafanie input)

@kbrock
Copy link
Member Author

kbrock commented May 3, 2023

update:

  • rebased to latest master
  • fixed 2 rubocop whitespace issues

@kbrock
Copy link
Member Author

kbrock commented May 3, 2023

update:

  • pulled busting cache into own commit

kbrock added 5 commits May 4, 2023 18:12
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
@kbrock
Copy link
Member Author

kbrock commented May 4, 2023

update:

  • moved a change line from one commit to the busting cache commit (all worked, end result the same, but that commit would not have worked without this line change)
  • rebased

@miq-bot
Copy link
Member

miq-bot commented May 4, 2023

Checked commits kbrock/manageiq@126eeb6~...029bc1b with ruby 2.6.10, rubocop 1.28.2, haml-lint 0.35.0, and yamllint
4 files checked, 0 offenses detected
Everything looks fine. 🍰

@kbrock
Copy link
Member Author

kbrock commented May 12, 2023

Just ran into this today. This will speed up timelines quite a bit.

@Fryguy
Copy link
Member

Fryguy commented May 12, 2023

LGTM - merging.

@Fryguy Fryguy merged commit 52c3b39 into ManageIQ:master May 12, 2023
9 checks passed
@kbrock kbrock deleted the miq_expression_to_ruby branch May 15, 2023 02:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants