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

feat: EXPOSED-238 Support EXPLAIN statements #2022

Merged
merged 1 commit into from
Mar 5, 2024

Conversation

bog-walk
Copy link
Member

@bog-walk bog-walk commented Mar 4, 2024

explain() takes any valid SELECT, INSERT, UPDATE, DELETE etc statement in its lambda body.
It blocks the execution of this internal statement and uses it to prepare an EXPLAIN query, which returns a result set of query execution path details (very different depending on database).
It acts like a standard Query in that it will not be executed until it is iterated over in some way:

val result = explain {
    Countries.select(Countries.id).where { Countries.code like "A%" }
}.toList()

println(result)
// PostgreSQL example
// QUERY PLAN=Seq Scan on countries  (cost=0.00..25.38 rows=6 width=4)
// QUERY PLAN=  Filter: ((country_code)::text ~~ 'A%'::text)

explain() blocks execution of the lambda statement by using 2 new Transaction properties.
1 of these properties makes sure that the lambda statement is captured so it can be passed to the ExplainQuery constructor, since not all statement functions return Statement<*> (namely update() and delete() return numbers).

Next steps:

  • Oracle supports this but the returned value is not a ResultSet. Instead, EXPLAIN PLAN expects an output table to exist for holding the result rows. Still need to decide if this is a table Exposed should create (and later drop) or if responsibility should go to the user. More details at EXPOSED-308.
  • SQL Server also supports this but the return value is an XML document. It should be possible to retrieve the contents as text.
  • ExplainResultRow is introduced to hold the field-value mapping from the result set because ResultRow's logic is too specific to Exposed table columns and expressions. It acts in a very similar way but is currently only set up to output the string results (as above) and should have getters and some API functions added. More details at EXPOSED-309.

Not supported:

  • DAO statements: It seems counter-intuitive to allow a DAO operation inside explain(), but this view may be wrong. Blocking execution would also mean blocking all the extra entity steps under-the-hood and in the cache. If requested, starting with SELECT would be the easiest to support (and its the most common use for EXPLAIN).
  • Batch statements: Depending on the underlying database and whether batching is actually supported, this works. But if batching isn't actually implemented by the driver, it attempts to wrap each individual statement with an EXPLAIN and returns the results of the last one. If there is a use case for querying the execution of batch operations over the single operation, this will need to be addressed.

Add ExplianQuery class that processes EXPLAIN statements for all valid wrapped
statements. The constructor uses 2 new Transaction properties to ensure that the
wrapped statements are not executed and that the internal statements is passed to
the invoking instance.

Add an ExplainResultRow class so that the explain query can be executed and iterated
over in a similar manner to a standard query. This class currently is only good
for printing a readable string version of the results and needs getters.

Add unit tests.
@bog-walk bog-walk linked an issue Mar 4, 2024 that may be closed by this pull request
@bog-walk bog-walk requested review from e5l and joc-a March 4, 2024 20:14
Copy link
Member

@e5l e5l left a comment

Choose a reason for hiding this comment

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

Please note: output of explain is version specific, so changes could be flaky with patch updates

@bog-walk
Copy link
Member Author

bog-walk commented Mar 5, 2024

Noted! One of the reasons I don't think an attempt should be made to define/determine the output in a restrictive way. The user being able to print the potentially changing output will hopefully suffice for now.

@bog-walk bog-walk merged commit 8ab7414 into main Mar 5, 2024
5 checks passed
@bog-walk bog-walk deleted the bog-walk/support-explain-query branch March 5, 2024 23:36
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.

Explain keyword support
2 participants