@@ -97,15 +97,27 @@ def write_query?(sql) # :nodoc:
97
97
!READ_QUERY . match? ( sql )
98
98
end
99
99
100
- def explain ( arel , binds = [ ] )
101
- sql = "EXPLAIN #{ to_sql ( arel , binds ) } "
102
- start = Concurrent . monotonic_time
103
- result = exec_query ( sql , "EXPLAIN" , binds )
104
- elapsed = Concurrent . monotonic_time - start
100
+ def explain ( arel , binds = [ ] , options = [ ] )
101
+ sql = build_explain_clause ( options ) + " " + to_sql ( arel , binds )
102
+ start = Process . clock_gettime ( Process :: CLOCK_MONOTONIC )
103
+ result = internal_exec_query ( sql , "EXPLAIN" , binds )
104
+ elapsed = Process . clock_gettime ( Process :: CLOCK_MONOTONIC ) - start
105
105
106
106
MySQL ::ExplainPrettyPrinter . new . pp ( result , elapsed )
107
107
end
108
108
109
+ def build_explain_clause ( options = [ ] )
110
+ return "EXPLAIN" if options . empty?
111
+
112
+ explain_clause = "EXPLAIN #{ options . join ( " " ) . upcase } "
113
+
114
+ if analyze_without_explain? && explain_clause . include? ( "ANALYZE" )
115
+ explain_clause . sub ( "EXPLAIN " , "" )
116
+ else
117
+ explain_clause
118
+ end
119
+ end
120
+
109
121
def each_hash ( result ) # :nodoc:
110
122
if block_given?
111
123
# FIXME: This is C in mysql2 gem and I just made simplest Ruby
@@ -185,6 +197,11 @@ def discard! # :nodoc:
185
197
#
186
198
187
199
private
200
+ # https://mariadb.com/kb/en/analyze-statement/
201
+ def analyze_without_explain?
202
+ mariadb? && database_version >= "10.1.0"
203
+ end
204
+
188
205
def text_type? ( type )
189
206
TYPE_MAP . lookup ( type ) . is_a? ( Type ::String ) || TYPE_MAP . lookup ( type ) . is_a? ( Type ::Text )
190
207
end
0 commit comments