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

[WIP] Parser return lifts #548

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

masonedmison
Copy link

@masonedmison masonedmison commented Dec 23, 2024

Problem

As part of discussions with @deusaquilus, he pointed out that "lifts" can be gotten from the parser instead of calling ExtractLifts. Calling ExtractLifts ends up being quite an expensive operation.

Solution

Within the quote macro, "lifts" are gotten from the parser instead of by executing ExtractLifts.

Checklist

  • Unit test all changes*
  • Update README.md if applicable
  • Add [WIP] to the pull request title if it's work in progress
  • Squash commits that aren't meaningful changes
  • Run changes made to existing tests by @deusaquilus
  • Run JProfiler against the compilation of quill-sql-tests and compare with a previous run
    in which lifts are gotten from ExtractLifts in the quote macro.

*: I believe the existing tests should cover all of the cases to test.

@getquill/maintainers

Comment on lines 151 to 158
List(),
List(EagerPlanter("foo", _, idB1)),
List(
QuotationVase(
Quoted(Infix(List("dyn1 || ", ""), List(ScalarTag(idB1, _)), false, false, QV), List(EagerPlanter("foo", _, idB)), Nil),
Quoted(Infix(List("dyn1 || ", ""), List(ScalarTag(idB, _)), false, false, QV), List(EagerPlanter("foo", _, idB2)), Nil),
idA1
)
)
) if (idA == idA1 && idB == idB1) =>
) if (idA == idA1 && idB == idB1 && idB == idB2) =>
Copy link
Author

@masonedmison masonedmison Dec 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly how q is evaluated, where q is

        val q = quote {
          sql"#$a || ${lift("foo")}".as[String]
        }

then

  • The "lift" macro fires first which returns EagerPlanter("foo", ...).unquote
  • Quote macro is called which passes '{EagerPlanter("foo").unquote} to the parser
  • QuotationParser fires first on UprootableUnquote where expr is
    EagerPlanter("foo") and adds EagerPlanter("foo") to Lifts.lifts
  • InfixParser then fires, as part of parsing ExtractLifts is called which gets the
    "foo" lift.

which, given that we are now "getting" lifts from the parser, makes sense the EagerPlanter("foo") would be now included in the lifts of the returned Quoted.

It's not clear to me, though, if this will yield any difference in behavior. I have a TODO for this.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic sounds right. The actual EagerPlanter(foo) is supposed to live inside the QuotationVase. I don’t think the ExtractLifts inside InfixParser is even necessary anymore and you should try to remove it.

Copy link
Author

@masonedmison masonedmison Dec 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t think the ExtractLifts inside InfixParser is even necessary anymore and you should try to remove it.

I'll start looking into this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@deusaquilus Indeed, you are right; simply getting the "lifts" and "pluckableUnquotes" from the Lifts context after parsing the Params seems to work: all of the tests with InfixTest pass.

Just pushed up a commit with this change.

@@ -370,7 +370,7 @@ class QuotationTest extends Spec with Inside {
qqq must matchPattern {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO @masonedmison I still need to convince myself that this is a sound change

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks alright to me. We can talk about it when I’m back in a couple days.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants