lib/shiba/explain/postgres_explain.rb in shiba-0.9.2 vs lib/shiba/explain/postgres_explain.rb in shiba-0.9.3
- old
+ new
@@ -15,25 +15,24 @@
@state = old_state
end
def transform_node(node, array)
case node['Node Type']
- when "Limit", "LockRows", "Aggregate", "Unique", "Sort", "Hash", "ProjectSet"
+ when "Limit", "LockRows", "Aggregate", "Unique", "Sort", "Hash", "ProjectSet", "Materialize"
recurse_plans(node, array)
- when "Nested Loop"
- with_state(join_type: node["Join Type"]) do
+ when "Hash Join", "Merge Join", "Nested Loop", "BitmapOr"
+ with_state(join_type: node['Node Type']) do
recurse_plans(node, array)
end
- when "Hash Join"
- join_fields = extract_join_key_parts(node['Hash Cond'])
- with_state(join_fields: join_fields, join_type: "Hash") do
- recurse_plans(node, array)
- end
when "Bitmap Heap Scan"
with_state(table: node['Relation Name']) do
recurse_plans(node, array)
end
+ when "Subquery Scan"
+ with_state(subquery: true) do
+ recurse_plans(node, array)
+ end
when "Seq Scan"
array << {
"table" => node["Relation Name"],
"access_type" => "ALL",
"key" => nil,
@@ -46,35 +45,57 @@
used_key_parts = extract_used_key_parts(node['Index Cond'])
else
used_key_parts = []
end
+ if @state[:join_type] == 'BitmapOr'
+ access_type = "intersect"
+ else
+ access_type = "ref"
+ end
+
h = {
"table" => node["Relation Name"] || @state[:table],
- "access_type" => "ref",
+ "access_type" => access_type,
"key" => node["Index Name"],
"used_key_parts" => used_key_parts
}
if node['Node Type'] == "Index Only Scan"
h['using_index'] = true
end
array << h
+ when "Result"
+ # TBD: What the hell is here? seems like queries that short-circuit end up here?
+ array << {
+ "extra" => "No tables used"
+ }
else
+ debugger
raise "unhandled node: #{node}"
end
array
end
def extract_used_key_parts(cond)
- conds = Parsers::PostgresExplainIndexConditions.new(cond)
- conds.fields
+ begin
+ conds = Parsers::PostgresExplainIndexConditions.new(cond)
+ conds.fields
+ rescue Parsers::BadParse => e
+ debugger
+ {}
+ end
end
def extract_join_key_parts(cond)
- conds = Parsers::PostgresExplainIndexConditions.new(cond)
- conds.join_fields
+ begin
+ conds = Parsers::PostgresExplainIndexConditions.new(cond)
+ conds.join_fields
+ rescue Parsers::BadParse => e
+ debugger
+ {}
+ end
end
def recurse_plans(node, array)
node['Plans'].each do |n|
transform_node(n, array)