Ecto - where/3 and or_where/3 different compile behaviour

Hey there, still learning elixir with a python background, I came across an error that I can not fully understand.

I’m building an Ecto query dynamically, I have several functions handling several filters that I compose reducing the filter enum. This is a sample of what I’m doing:

...
def make_query(some_id, filters \\ %{}) do
    from(
      t in Thing, as: :thing,
      left_join: s in assoc(s, :stuff), as: :stuff,
      where: t.id == ^some_id,
      group_by: t.id
    )
    |> apply_filters(filters)
    |> Repo.all()
  end

  defp apply_filters(query, filters) do
    Enum.reduce(filters, query, &apply_filter/2)
  end

  defp apply_filter({:name, name}, query) when present?(name) do
    where(query, [thing: t], fragment("lower(?) = lower(?)", t.name, ^name))
  end

  defp apply_filter({:some_bool, bool_value}, query) when present?(bool_value) do
    case bool_value do
      0 -> where(query, [stuff: s], is_nil(s.id))
      _ -> where(query, [stuff: s], not is_nil(s.id))
    end
  end

 ... some other filter funcs, and then:


  defp apply_filter({:fuzzy, text}, query) when present?(text) do
    Enum.reduce(String.split(text), query, &apply_fuzzy/2)
  end

  defp apply_fuzzy(word, query) when present?(word) do
    where(
        query,
        [thing: t, stuff: s],
        (fragment("metaphone(?, 2) = metaphone(?, 2)", t.foo, ^word) or
           fragment("metaphone(?, 2) = metaphone(?, 2)", t.bar, ^word) or
           fragment("metaphone(?, 2) = metaphone(?, 2)", s.baz, ^word)) and
          (fragment("levenshtein(lower(?),lower(?)) < 4", t.foo, ^word) or
             fragment("levenshtein(lower(?),lower(?)) < 4", t.bar, ^word) or
             fragment("levenshtein(lower(?),lower(?)) < 4", s.baz, ^word))
      )
  end
...

The problem here shows up in the apply_fuzzy/2, if I run this everything works fine, but if I change the where in apply_fuzzy/2 with or_where, I get a compilation error:

  defp apply_fuzzy(word, query) when present?(word) do
    or_where(
        query,
        ....

warning: variable "t" does not exist and is being expanded to "t()", please use parentheses to remove the ambiguity or change the variable name
  lib/app/thing/loader.ex:125: App.Thing.Loader.apply_fuzzy/2

warning: variable "t" does not exist and is being expanded to "t()", please use parentheses to remove the ambiguity or change the variable name
  lib/app/thing/loader.ex:125: App.Thing.Loader.apply_fuzzy/2

warning: variable "s" does not exist and is being expanded to "s)", please use parentheses to remove the ambiguity or change the variable name
  lib/app/thing/loader.ex:126: App.Thing.apply_fuzzy/2


== Compilation error in file lib/app/thing/loader.ex ==
** (CompileError) lib/app/thing/loader.ex:126: cannot use ^word outside of match clauses
    (elixir 1.13.4) expanding macro: Kernel.or/2
    lib/app/thing/loader.ex:126: App.Thing.Loader.apply_fuzzy/2
    (elixir 1.13.4) expanding macro: Kernel.or/2

Docs says:

An OR where query expression.

Behaves exactly the same as where except it combines with any previous expression by using an OR.

I’m considering “Behaves exactly the same as where” to mean that I can replace one with another to only change and AND with an OR, is this assumption wrong? What am I missing?

I’m not looking for a solution to my fuzzy query, I’m only trying to understand why I get the compilation error.

The error messages suggest that the or_where macro isn’t available in the scope; do you perhaps have a restricted import (import Ecto.Query, only: [where: ...]) someplace?