1
1
# frozen_string_literal: true
2
2
3
3
require 'appmap/event'
4
+ require 'appmap/hook/method'
4
5
5
6
module AppMap
6
7
module Handler
@@ -21,6 +22,7 @@ def to_h
21
22
sql : payload [ :sql ] ,
22
23
database_type : payload [ :database_type ]
23
24
} . tap do |sql_query |
25
+ sql_query [ :query_plan ] = payload [ :query_plan ] if payload [ :query_plan ]
24
26
%i[ server_version ] . each do |attribute |
25
27
sql_query [ attribute ] = payload [ attribute ] if payload [ attribute ]
26
28
end
@@ -44,15 +46,30 @@ def examine(payload, sql:)
44
46
return unless ( examiner = build_examiner )
45
47
46
48
if AppMap . explain_queries? && examiner . in_transaction? && examiner . database_type == :postgres
47
- if sql =~ /\A (SELECT|INSERT|DELETE|UPDATE|WITH)/i
48
- examiner . execute_query 'SAVEPOINT appmap_sql_examiner'
49
- begin
50
- plan = examiner . execute_query ( %(EXPLAIN #{ sql } ) )
51
- payload [ :query_plan ] = plan . map { |line | line [ :'QUERY PLAN' ] } . join ( "\n " )
52
- examiner . execute_query 'RELEASE SAVEPOINT appmap_sql_examiner'
53
- rescue
54
- warn "Exception occurred explaining query: #{ $!} "
55
- examiner . execute_query 'ROLLBACK TO SAVEPOINT appmap_sql_examiner'
49
+ if sql =~ /\A (SELECT|INSERT|UPDATE|DELETE|WITH)/i
50
+ savepoint_established = \
51
+ begin
52
+ examiner . execute_query 'SAVEPOINT appmap_sql_examiner'
53
+ true
54
+ rescue
55
+ # Probably: Sequel::DatabaseError: PG::InFailedSqlTransaction
56
+ byebug
57
+ warn $!
58
+ false
59
+ end
60
+
61
+ if savepoint_established
62
+ plan = nil
63
+ begin
64
+ plan = examiner . execute_query ( %(EXPLAIN #{ sql } ) )
65
+ rescue
66
+ warn "Exception occurred explaining query: #{ $!} "
67
+ examiner . execute_query 'ROLLBACK TO SAVEPOINT appmap_sql_examiner'
68
+ end
69
+ if plan
70
+ payload [ :query_plan ] = plan . map { |line | line [ :'QUERY PLAN' ] } . join ( "\n " )
71
+ examiner . execute_query 'RELEASE SAVEPOINT appmap_sql_examiner'
72
+ end
56
73
end
57
74
end
58
75
end
@@ -124,6 +141,8 @@ def execute_query(sql)
124
141
def call ( _ , started , finished , _ , payload ) # (name, started, finished, unique_id, payload)
125
142
return if AppMap . tracing . empty?
126
143
144
+ return if Thread . current [ AppMap ::Hook ::Method ::HOOK_DISABLE_KEY ] == true
145
+
127
146
reentry_key = "#{ self . class . name } #call"
128
147
return if Thread . current [ reentry_key ] == true
129
148
0 commit comments