@@ -319,15 +319,48 @@ defmodule Ecto.Adapters.SQLite3.Connection do
319
319
320
320
@ impl true
321
321
def explain_query ( conn , query , params , opts ) do
322
- case query ( conn , build_explain_query ( query ) , params , opts ) do
322
+ type = Keyword . get ( opts , :type , :query_plan )
323
+
324
+ case query ( conn , build_explain_query ( query , type ) , params , opts ) do
323
325
{ :ok , % Exqlite.Result { } = result } ->
324
- { :ok , SQL . format_table ( result ) }
326
+ case type do
327
+ :query_plan -> { :ok , format_query_plan_explain ( result ) }
328
+ :instructions -> { :ok , SQL . format_table ( result ) }
329
+ end
325
330
326
331
error ->
327
332
error
328
333
end
329
334
end
330
335
336
+ defp build_explain_query ( query , :query_plan ) do
337
+ IO . iodata_to_binary ( [ "EXPLAIN QUERY PLAN" , query ] )
338
+ end
339
+
340
+ defp build_explain_query ( query , :instructions ) do
341
+ IO . iodata_to_binary ( [ "EXPLAIN " , query ] )
342
+ end
343
+
344
+ # Mimics the ASCII format of the sqlite CLI
345
+ defp format_query_plan_explain ( % { rows: rows } ) do
346
+ { lines , _ } =
347
+ rows
348
+ |> Enum . chunk_every ( 2 , 1 , [ nil ] )
349
+ |> Enum . map_reduce ( 0 , fn [ [ id , parent , _ , text ] , next ] , depth ->
350
+ { branch , next_depth } =
351
+ case { id , parent , next } do
352
+ { id , _ , [ _ , id , _ , _ ] } -> { "|--" , depth + 1 }
353
+ { _ , p , [ _ , p , _ , _ ] } -> { "|--" , depth }
354
+ _ -> { "`--" , depth - 1 }
355
+ end
356
+
357
+ formatted_line = String . duplicate ( "| " , depth ) <> branch <> text
358
+ { formatted_line , next_depth }
359
+ end )
360
+
361
+ Enum . join ( [ "QUERY PLAN" | lines ] , "\n " )
362
+ end
363
+
331
364
##
332
365
## DDL
333
366
##
@@ -654,10 +687,6 @@ defmodule Ecto.Adapters.SQLite3.Connection do
654
687
{ "SELECT name FROM sqlite_master WHERE type='table' AND name=? LIMIT 1" , [ table ] }
655
688
end
656
689
657
- def build_explain_query ( query ) do
658
- IO . iodata_to_binary ( [ "EXPLAIN " , query ] )
659
- end
660
-
661
690
##
662
691
## Query generation
663
692
##
0 commit comments