Commit f1f49028 authored by Kamil Trzciński's avatar Kamil Trzciński

Ensure that transaction boundaries are always parsed

Since non-materialised transactions can be init in a suppressed
block we need to ensure that transaction boundaries are always parsed.
The exception raised in a suppressed block will generate rollback
outside resulting in a wrong behavior.
parent a596dc70
...@@ -58,7 +58,7 @@ module Gitlab ...@@ -58,7 +58,7 @@ module Gitlab
return unless parsed return unless parsed
analyzers.each do |analyzer| analyzers.each do |analyzer|
next if analyzer.suppressed? next if analyzer.suppressed? && !analyzer.requires_tracking?(parsed)
analyzer.analyze(parsed) analyzer.analyze(parsed)
rescue StandardError, QueryAnalyzers::Base::QueryAnalyzerError => e rescue StandardError, QueryAnalyzers::Base::QueryAnalyzerError => e
......
...@@ -11,6 +11,10 @@ module Gitlab ...@@ -11,6 +11,10 @@ module Gitlab
Thread.current[self.suppress_key] Thread.current[self.suppress_key]
end end
def self.requires_tracking?(parsed)
false
end
def self.suppress=(value) def self.suppress=(value)
Thread.current[self.suppress_key] = value Thread.current[self.suppress_key] = value
end end
......
...@@ -36,10 +36,13 @@ module Gitlab ...@@ -36,10 +36,13 @@ module Gitlab
Feature.enabled?(:detect_cross_database_modification, default_enabled: :yaml) Feature.enabled?(:detect_cross_database_modification, default_enabled: :yaml)
end end
def self.requires_tracking?(parsed)
# The transaction boundaries always needs to be tracked regardless of suppress behavior
self.transaction_begin?(parsed) || self.transaction_end?(parsed)
end
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize
def self.analyze(parsed) def self.analyze(parsed)
return if in_factory_bot_create?
database = ::Gitlab::Database.db_config_name(parsed.connection) database = ::Gitlab::Database.db_config_name(parsed.connection)
sql = parsed.sql sql = parsed.sql
...@@ -62,6 +65,7 @@ module Gitlab ...@@ -62,6 +65,7 @@ module Gitlab
end end
return unless self.in_transaction? return unless self.in_transaction?
return if in_factory_bot_create?
# PgQuery might fail in some cases due to limited nesting: # PgQuery might fail in some cases due to limited nesting:
# https://github.com/pganalyze/pg_query/issues/209 # https://github.com/pganalyze/pg_query/issues/209
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment