@@ -713,12 +713,27 @@ defmodule Ecto.Query.Builder do
713713 { :{} , [ ] , [ dot , [ ] , [ ] ] }
714714 end
715715
716+ defp escape_field! ( source , field , _vars ) when is_atom ( source ) do
717+ as = { :{} , [ ] , [ :as , [ ] , [ source ] ] }
718+ field = quoted_atom_or_string! ( field , "field/2" )
719+ dot = { :{} , [ ] , [ :. , [ ] , [ as , field ] ] }
720+ { :{} , [ ] , [ dot , [ ] , [ ] ] }
721+ end
722+
723+ defp escape_field! ( { :^ , _ , [ _ ] } = expr , field , _vars ) do
724+ value = quoted_atom! ( expr , "field/2" )
725+ as = { :{} , [ ] , [ :as , [ ] , [ value ] ] }
726+ field = quoted_atom_or_string! ( field , "field/2" )
727+ dot = { :{} , [ ] , [ :. , [ ] , [ as , field ] ] }
728+ { :{} , [ ] , [ dot , [ ] , [ ] ] }
729+ end
730+
716731 defp escape_field! ( expr , field , _vars ) do
717732 error! ( """
718733 cannot fetch field `#{ Macro . to_string ( field ) } ` from `#{ Macro . to_string ( expr ) } `. Can only fetch fields from:
719734
720735 * sources, such as `p` in `from p in Post`
721- * named bindings, such as `as(:post)` in `from Post, as: :post`
736+ * named bindings, such as `as(:post)` or `:post` in `from Post, as: :post`
722737 * parent named bindings, such as `parent_as(:post)` in a subquery
723738 """ )
724739 end
@@ -1376,6 +1391,12 @@ defmodule Ecto.Query.Builder do
13761391 { { :{} , [ ] , [ kind , [ ] , [ value ] ] } , field }
13771392 end
13781393
1394+ def quoted_type ( { :field , _ , [ expr , field ] } , _vars )
1395+ when is_atom ( field ) or is_binary ( field ) do
1396+ source = quoted_atom! ( expr , "field/2" )
1397+ { { :{} , [ ] , [ :as , [ ] , [ source ] ] } , field }
1398+ end
1399+
13791400 # Unquoting code here means the second argument of field will
13801401 # always be unquoted twice, one by the type checking and another
13811402 # in the query itself. We are assuming this is not an issue
@@ -1390,6 +1411,11 @@ defmodule Ecto.Query.Builder do
13901411 { { :{} , [ ] , [ kind , [ ] , [ value ] ] } , code }
13911412 end
13921413
1414+ def quoted_type ( { :field , _ , [ expr , { :^ , _ , [ code ] } ] } , _vars ) do
1415+ source = quoted_atom! ( expr , "field/2" )
1416+ { { :{} , [ ] , [ :as , [ ] , [ source ] ] } , code }
1417+ end
1418+
13931419 # Interval
13941420 def quoted_type ( { :datetime_add , _ , [ _ , _ , _ ] } , _vars ) , do: :naive_datetime
13951421 def quoted_type ( { :date_add , _ , [ _ , _ , _ ] } , _vars ) , do: :date
0 commit comments