Require db.pg statically so tree shaking can proceed - #11
Merged
Conversation
Adopted from #10 by sundbp, extended to the java.sql shim and resolved against main, which had moved underneath it. jdbc.core reached the postgres driver through (resolve (symbol "db.pg" n)) behind a runtime require. A reachable call to resolve stops jolt from building a sound whole-program call graph, so jolt build --tree-shake skipped shaking entirely for any program that loaded jdbc.core, sqlite-only ones included. A runtime require is also the wrong edge for an AOT binary, which has no source roots to load db.pg from later. The reason that indirection existed was that a compile-time db.pg/foo reference used to be read as a host class. That is no longer so, and the namespace alias works, so both callers now require db.pg statically and call pg/connect, pg/close, pg/exec, pg/all and pg/all-raw directly. db.jdbc-shim had grown its own copy of the same pgfn trick, which matters more than the jdbc.core one: jdbc.core is on its way out when the switchover lands, while the shim is what stays. Fixing only the file in the PR would have carried the defect into the new architecture. A sqlite-only app still does not need libpq. Loading db.pg only declares the bindings; ffi/defcfn resolves a symbol on first call. Checked against a project whose deps.edn points :jolt/native at a libpq that does not exist: it builds, runs and returns rows. Verified the actual claim rather than the diff. Against main, jolt build --tree-shake reports "tree-shake skipped (reachable code resolves vars at runtime)". With this, it reports "tree-shake kept 336 of 764 defs (core 237/659)" and the resulting binary runs. Co-authored-by: sundbp <sundbp@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adopts #10 by @sundbp, extended to the java.sql shim and resolved against main, which had moved underneath it.
The problem, as #10 diagnosed it
jdbc.corereached the postgres driver through(resolve (symbol "db.pg" n))behind a runtimerequire. A reachable call toresolvestops jolt from building a sound whole-program call graph, sojolt build --tree-shakeskipped shaking entirely for any program that loadedjdbc.core, sqlite-only ones included. A runtimerequireis also the wrong dependency edge for an AOT binary, which has no source roots to loaddb.pgfrom later.The reason the indirection existed is in the comment it replaces: a compile-time
db.pg/fooreference used to be read as a host class. That is no longer the case, and the namespace alias works.What changed relative to #10
The PR conflicted because main moved:
pg-placeholdersnow lives indb.pgand is applied insidedb.pg/run, sopg-evalno longer rewrites, andexecute!returns affected rows on postgres.More importantly,
db.jdbc-shimhad since grown its own copy of the samepgfntrick. That one matters more than thejdbc.coreone:jdbc.coreis on its way out when the clojure.jdbc switchover lands, while the shim is what stays. Adopting the PR as written would have fixed the file that is being deleted and left the defect in the file that survives. Both are now static.Verification
I checked the claim rather than the diff, since the whole point is a build-time property no unit test covers.
Before, on main:
After:
and the resulting binary runs and returns rows.
The load-bearing claim is that a sqlite-only app still does not need libpq, which is easy to assert and easy to get wrong, so I tested it directly: a project whose
deps.ednpoints:jolt/nativeat a libpq that does not exist builds, runs and returns{:name "ada"}. Loadingdb.pgonly declares the bindings;ffi/defcfnresolves a symbol on first call, not on load. The stale docstrings indb.pgthat promised lazy loading now say that instead.Suite is unchanged at 91 checks, sqlite-only and against postgres 16.