Skip to content

Conversation

@greg-rychlewski
Copy link
Member

@greg-rychlewski greg-rychlewski commented Jan 10, 2026

Pre-requisite to removing it from the adapters

def splice!(value, param_num) do
if is_list(value) do
value
Enum.map(value, fn _ -> {:^, [], [param_num]} end)
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the weirdest part. Because we use length(params) to set the parameter indexes and we don't know how many are in here until runtime.

Doing it this way keeps parameter counting in the rest of the builder the same and planner cleans everything up anyways.

Copy link
Member

Choose a reason for hiding this comment

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

It has been a while, so can you please remind me how it works in this case? fragment(..., splice(^foo), ^bar) How do we know the parameter position for ^bar? I guess the planner goes increment all parameters later on, whenever it sees a splice or an in?

Copy link
Member Author

@greg-rychlewski greg-rychlewski Jan 10, 2026

Choose a reason for hiding this comment

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

Yeah basically like that.

To be more specific, when normalizing a query the prewalk function in the planner has an accumulator that keeps track of the current query parameter number. The counter is initialized to 0 for queries and initialized to the current parameter count when doing stuff like insert_all or conflict queries. Whenever the prewalker sees a query parameter it just increments the parameter counter.

For :in and the current implementation of :splice they have a bit of a trick in the prewalker. Since we don't know the length of the list at compile time we treat the whole list as one query parameter then in the prewalker it shifts the counter by the length of the list. See here for :in and here for :splice. Then in the adapter it sees the AST for these things and does the actual splicing of the SQL text. The parameter list itself is spliced by the planner here.

Copy link
Member

@josevalim josevalim left a comment

Choose a reason for hiding this comment

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

If you are happy with it, I am happy with it!

@greg-rychlewski greg-rychlewski merged commit bf24234 into elixir-ecto:master Jan 11, 2026
7 checks passed
@greg-rychlewski greg-rychlewski deleted the runtime_splice branch January 11, 2026 00:28
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