@@ -222,10 +222,18 @@ if Code.ensure_loaded?(MyXQL) do
222222 end
223223
224224 @ impl true
225- # DB explain opts are deprecated, so they aren't used to build the explain query .
225+ # DB explain opts, except format, are deprecated .
226226 # See Notes at https://dev.mysql.com/doc/refman/5.7/en/explain.html
227227 def explain_query ( conn , query , params , opts ) do
228- case query ( conn , build_explain_query ( query ) , params , opts ) do
228+ { explain_opts , opts } = Keyword . split ( opts , ~w[ format] a )
229+ map_format? = { :format , :map } in explain_opts
230+
231+ case query ( conn , build_explain_query ( query , explain_opts ) , params , opts ) do
232+ { :ok , % MyXQL.Result { rows: rows } } when map_format? ->
233+ json_library = MyXQL . json_library ( )
234+ decoded_result = Enum . map ( rows , & json_library . decode! ( & 1 ) )
235+ { :ok , decoded_result }
236+
229237 { :ok , % MyXQL.Result { } = result } ->
230238 { :ok , SQL . format_table ( result ) }
231239
@@ -234,11 +242,16 @@ if Code.ensure_loaded?(MyXQL) do
234242 end
235243 end
236244
237- def build_explain_query ( query ) do
245+ def build_explain_query ( query , [ ] ) do
238246 [ "EXPLAIN " , query ]
239247 |> IO . iodata_to_binary ( )
240248 end
241249
250+ def build_explain_query ( query , [ format: value ] ) do
251+ [ "EXPLAIN #{ String . upcase ( "#{ format_to_sql ( value ) } " ) } " , query ]
252+ |> IO . iodata_to_binary ( )
253+ end
254+
242255 ## Query generation
243256
244257 binary_ops =
@@ -1080,6 +1093,9 @@ if Code.ensure_loaded?(MyXQL) do
10801093 [ ?` , name , ?` ]
10811094 end
10821095
1096+ defp format_to_sql ( :map ) , do: "FORMAT=JSON"
1097+ defp format_to_sql ( :text ) , do: "FORMAT=TRADITIONAL"
1098+
10831099 defp intersperse_map ( list , separator , mapper , acc \\ [ ] )
10841100 defp intersperse_map ( [ ] , _separator , _mapper , acc ) ,
10851101 do: acc
0 commit comments