in lib/pg_query/fingerprint.rb [67:120]
def fingerprint_node(node, hash, parent_node_name = nil, parent_field_name = nil)
return if ignored_node_type?(node)
if node.is_a?(Node)
return if node.node.nil?
node_val = node[node.node.to_s]
unless ignored_node_type?(node_val)
unless node_val.is_a?(List)
postgres_node_name = node_protobuf_field_name_to_json_name(node.class, node.node)
hash.update(postgres_node_name)
end
fingerprint_value(node_val, hash, parent_node_name, parent_field_name, false)
end
return
end
postgres_node_name = node.class.name.split('::').last
node.to_h.keys.sort.each do |field_name|
val = node[field_name.to_s]
postgres_field_name = node_protobuf_field_name_to_json_name(node.class, field_name)
case postgres_field_name
when 'location'
next
when 'name'
next if [PrepareStmt, ExecuteStmt, DeallocateStmt].include?(node.class)
next if node.is_a?(ResTarget) && parent_node_name == 'SelectStmt' && parent_field_name == 'targetList'
when 'gid', 'options', 'savepoint_name'
next if node.is_a?(TransactionStmt)
when 'portalname'
next if [DeclareCursorStmt, FetchStmt, ClosePortalStmt].include?(node.class)
when 'relname'
next if node.is_a?(RangeVar) && node.relpersistence == 't'
if node.is_a?(RangeVar)
fingerprint_value(val.gsub(/\d{2,}/, ''), hash, postgres_node_name, postgres_field_name, true)
next
end
when 'stmt_len'
next if node.is_a?(RawStmt)
when 'stmt_location'
next if node.is_a?(RawStmt)
when 'kind'
if node.is_a?(A_Expr) && (val == :AEXPR_OP_ANY || val == :AEXPR_IN)
fingerprint_value(:AEXPR_OP, hash, postgres_node_name, postgres_field_name, true)
next
end
end
fingerprint_value(val, hash, postgres_node_name, postgres_field_name, true)
end
end