@@ -132,7 +132,7 @@ defmodule Ecto.Adapters.PostgresTest do
132132
133133 assert all ( query ) ==
134134 ~s{ WITH RECURSIVE "tree" AS } <>
135- ~s{ (SELECT c0 ."id" AS "id", 1 AS "depth" FROM "categories" AS c0 WHERE (c0 ."parent_id" IS NULL) } <>
135+ ~s{ (SELECT sc0 ."id" AS "id", 1 AS "depth" FROM "categories" AS sc0 WHERE (sc0 ."parent_id" IS NULL) } <>
136136 ~s{ UNION ALL } <>
137137 ~s{ (SELECT c0."id", t1."depth" + 1 FROM "categories" AS c0 } <>
138138 ~s{ INNER JOIN "tree" AS t1 ON t1."id" = c0."parent_id")) } <>
@@ -171,8 +171,8 @@ defmodule Ecto.Adapters.PostgresTest do
171171
172172 assert all ( query ) ==
173173 ~s{ WITH "comments_scope" AS (} <>
174- ~s{ SELECT c0 ."entity_id" AS "entity_id", c0 ."text" AS "text" } <>
175- ~s{ FROM "comments" AS c0 WHERE (c0 ."deleted_at" IS NULL)) } <>
174+ ~s{ SELECT sc0 ."entity_id" AS "entity_id", sc0 ."text" AS "text" } <>
175+ ~s{ FROM "comments" AS sc0 WHERE (sc0 ."deleted_at" IS NULL)) } <>
176176 ~s{ SELECT p0."title", c1."text" } <>
177177 ~s{ FROM "posts" AS p0 } <>
178178 ~s{ INNER JOIN "comments_scope" AS c1 ON c1."entity_id" = p0."guid" } <>
@@ -212,7 +212,7 @@ defmodule Ecto.Adapters.PostgresTest do
212212
213213 assert update_all ( query ) ==
214214 ~s{ WITH "target_rows" AS } <>
215- ~s{ (SELECT s0 ."id" AS "id" FROM "schema" AS s0 ORDER BY s0 ."id" LIMIT 10 FOR UPDATE SKIP LOCKED) } <>
215+ ~s{ (SELECT ss0 ."id" AS "id" FROM "schema" AS ss0 ORDER BY ss0 ."id" LIMIT 10 FOR UPDATE SKIP LOCKED) } <>
216216 ~s{ UPDATE "schema" AS s0 } <>
217217 ~s{ SET "x" = 123 } <>
218218 ~s{ FROM "target_rows" AS t1 } <>
@@ -233,13 +233,51 @@ defmodule Ecto.Adapters.PostgresTest do
233233
234234 assert delete_all ( query ) ==
235235 ~s{ WITH "target_rows" AS } <>
236- ~s{ (SELECT s0 ."id" AS "id" FROM "schema" AS s0 ORDER BY s0 ."id" LIMIT 10 FOR UPDATE SKIP LOCKED) } <>
236+ ~s{ (SELECT ss0 ."id" AS "id" FROM "schema" AS ss0 ORDER BY ss0 ."id" LIMIT 10 FOR UPDATE SKIP LOCKED) } <>
237237 ~s{ DELETE FROM "schema" AS s0 } <>
238238 ~s{ USING "target_rows" AS t1 } <>
239239 ~s{ WHERE (t1."id" = s0."id") } <>
240240 ~s{ RETURNING s0."id", s0."x", s0."y", s0."z", s0."w", s0."meta"}
241241 end
242242
243+ test "parent binding subquery and CTE" do
244+ initial_query =
245+ "categories"
246+ |> where ( [ c ] , c . id == parent_as ( :parent_category ) . id )
247+ |> select ( [ :id , :parent_id ] )
248+
249+ iteration_query =
250+ "categories"
251+ |> join ( :inner , [ c ] , t in "tree" , on: t . parent_id == c . id )
252+ |> select ( [ :id , :parent_id ] )
253+
254+ cte_query = initial_query |> union_all ( ^ iteration_query )
255+
256+ breadcrumbs_query =
257+ "tree"
258+ |> recursive_ctes ( true )
259+ |> with_cte ( "tree" , as: ^ cte_query )
260+ |> select ( [ t ] , % { breadcrumbs: fragment ( "STRING_AGG(?, ' / ')" , t . id ) } )
261+
262+ query =
263+ from ( c in "categories" ,
264+ as: :parent_category ,
265+ left_lateral_join: b in subquery ( breadcrumbs_query ) ,
266+ select: % { id: c . id , breadcrumbs: b . breadcrumbs }
267+ )
268+ |> plan ( )
269+
270+ assert all ( query ) ==
271+ ~s{ SELECT c0."id", s1."breadcrumbs" FROM "categories" AS c0 } <>
272+ ~s{ LEFT OUTER JOIN LATERAL } <>
273+ ~s{ (WITH RECURSIVE "tree" AS } <>
274+ ~s{ (SELECT ssc0."id" AS "id", ssc0."parent_id" AS "parent_id" FROM "categories" AS ssc0 WHERE (ssc0."id" = c0."id") } <>
275+ ~s{ UNION ALL } <>
276+ ~s{ (SELECT c0."id", c0."parent_id" FROM "categories" AS c0 } <>
277+ ~s{ INNER JOIN "tree" AS t1 ON t1."parent_id" = c0."id")) } <>
278+ ~s{ SELECT STRING_AGG(st0."id", ' / ') AS "breadcrumbs" FROM "tree" AS st0) AS s1 ON TRUE}
279+ end
280+
243281 test "select" do
244282 query = Schema |> select ( [ r ] , { r . x , r . y } ) |> plan ( )
245283 assert all ( query ) == ~s{ SELECT s0."x", s0."y" FROM "schema" AS s0}
@@ -682,7 +720,7 @@ defmodule Ecto.Adapters.PostgresTest do
682720 |> plan ( )
683721
684722 result =
685- "WITH \" cte1\" AS (SELECT s0 .\" id\" AS \" id\" , $1 AS \" smth\" FROM \" schema1\" AS s0 WHERE ($2)), " <>
723+ "WITH \" cte1\" AS (SELECT ss0 .\" id\" AS \" id\" , $1 AS \" smth\" FROM \" schema1\" AS ss0 WHERE ($2)), " <>
686724 "\" cte2\" AS (SELECT * FROM schema WHERE $3) " <>
687725 "SELECT s0.\" id\" , $4 FROM \" schema\" AS s0 INNER JOIN \" schema2\" AS s1 ON $5 " <>
688726 "INNER JOIN \" schema2\" AS s2 ON $6 WHERE ($7) AND ($8) " <>
0 commit comments