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

Remove the dynamic assumption of table field #8

Merged
merged 10 commits into from
Mar 10, 2022

Conversation

pmonson711
Copy link
Contributor

@pmonson711 pmonson711 commented Mar 9, 2022

Support complex order by statements via fragment + SQL AS

An example query utilizing bare AS in select:

query
|> select_merge([tbl: t], %{ virtual_column: fragment("?[1]->>'json_column' AS virtual_column", t.some_column) })
|> order_by(desc: fragment("virtual_column"))

UPDATE the AS approach won't work without further parsing of the select query which don't think is a good plan, I'm only going to support the 'matching select' approach below.

An example query same expr:

query
|> select_merge([tbl: t], %{ virtual_column: fragment("?[1]->>'json_column'", t.some_column) })
|> order_by([tbl: t], desc: fragment("?[1]->>'json_column'", t.some_column))

This should allow arbitrarily complex order by expressions by looking up the select statement with the matching expr as the order by or via a select result matching an SQL AS expr


  • Adds field_or_alias concept to ordering and page break that holds the
    previously held assumption of table column in as expr in the structs
  • Utilizes the field_or_alias for the Fob apply_keyset_comparison
    dynamics

TODO

- Adds field_or_alias concept to ordering and page break that holds the
  previously held assumption of table column in as expr in the structs
- Utilizes the field_or_alias for the Fob apply_keyset_comparison
  dynamics
@the-mikedavis
Copy link
Contributor

This is looking good so far. It's pretty nifty you can do that with dynamic/1

@pmonson711
Copy link
Contributor Author

One (maybe?) minor thing, that I haven't internalized yet, is what impact this may have on Haste. It appears it also deals with the PageBreak struct a bit, so I may need to separate the internal vs on the wire concerns to have a concept like this. Assuming this it might be prudent to only support the select AS form as it can be serialized down to column + value simply on the wire

NFIBrokerage/haste/lib/impl.ex

@the-mikedavis
Copy link
Contributor

Hmm yes seems like Haste will need to be updated to remove the assumption that the "criterion" (could be a more flexible replacement for "column") is a column (and therefore atom)

@pmonson711
Copy link
Contributor Author

I'm thinking that because Haste has both a server and a client component... I can keep the existing structure and purely do this as an enhancement in Fob. We can then update the contract for Haste if needed in a way that won't break systems during deployments of that update.

@pmonson711
Copy link
Contributor Author

I've proven this approach can work, but I'm stuck on building a field_or_alias in a way doesn't scream sql injections to Ecto. I imagine I could probably call into the Query.Builder modules in Ecto but all of the modules are undocumented, so I I'm hesitant to rush there.

@the-mikedavis
Copy link
Contributor

I think there's an acceptable amount of private API usage IMO. We're already destructuring on the opaque/private ecto query fields which could be broken in an ecto upgrade (although historically this seems to be pretty stable). Less is better but I think some private usage is warranted

@pmonson711
Copy link
Contributor Author

pmonson711 commented Mar 10, 2022

Just a note that as this commit point it would break all Haste implementations. update incoming to separate the this internal field from what Haste cares about.

Error Details
** (Protocol.UndefinedError) protocol Jason.Encoder not implemented for dynamic([{t, table}], table.relay_reference_number) of type Ecto.Query.DynamicExpr (a struct), Jason.Encoder protocol must always be explicitly implemented.

@pmonson711
Copy link
Contributor Author

One #9 is reviewed, I think this is done. I'm assuming we want release notes, after that Is there more I should add to the PR?

…three

Keep all changes internal for Haste
@pmonson711 pmonson711 marked this pull request as ready for review March 10, 2022 17:29
Copy link
Contributor

@the-mikedavis the-mikedavis left a comment

Choose a reason for hiding this comment

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

Sweet test cases 🚀

This looks good to me. You can add a new section to the CHANGELOG.md if you like or do that in a separate commit

lib/fob/fragment_builder.ex Outdated Show resolved Hide resolved
- Assuming we want a minor bump for new functionality? But perhaps we
  call this a patch as all the changes are internal
Coverage seems to happen which calling the fragment builder directly.
I'm assuming this is because test itself is a macro.
@pmonson711 pmonson711 merged commit a6ef115 into main Mar 10, 2022
@pmonson711 pmonson711 deleted the exp/allow-complex-order-by branch March 10, 2022 18:42
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