Skip to content

Commit

Permalink
AR does not send a semicolon after a SQL statement
Browse files Browse the repository at this point in the history
  • Loading branch information
camilo committed Dec 24, 2023
1 parent 6402f77 commit 8e73b3d
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
9 changes: 8 additions & 1 deletion lib/semian/activerecord_trilogy_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,14 @@ module ActiveRecordTrilogyAdapter
# this method to be ~20x faster in the common case vs matching the full regular expression
class << self
def query_allowlisted?(sql, *)
if !sql.end_with?("T") && !sql.end_with?("K") && !sql.end_with?("_1") && !sql.end_with?("_2")
# Any nesting pass _3 levels is won't get bypassed. I think that is fine once
# you are 3 level deep in nested transactions you have bigger problems.
unlikely_to_be_tx_control_statement = !sql.end_with?("T") && !sql.end_with?("K") && !sql.end_with?("_1")\
&& !sql.end_with?("_2")
# ActiveRecord does not send trailing spaces of ; we are in the realm of hand crafted queries here
unclear = sql.end_with?(" ") || sql.end_with?(";")

if unlikely_to_be_tx_control_statement && !unclear
false
else
QUERY_ALLOWLIST.match?(sql)
Expand Down
15 changes: 8 additions & 7 deletions test/adapters/activerecord_trilogy_adapter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,23 +306,23 @@ def test_semian_allows_rollback
@adapter.execute("START TRANSACTION;")

Semian[:mysql_testing].acquire do
@adapter.execute("ROLLBACK;")
@adapter.execute("ROLLBACK")
end
end

def test_semian_allows_rollback_with_marginalia
@adapter.execute("START TRANSACTION;")

Semian[:mysql_testing].acquire do
@adapter.execute("/*foo:bar*/ ROLLBACK;")
@adapter.execute("/*foo:bar*/ ROLLBACK")
end
end

def test_semian_allows_commit
@adapter.execute("START TRANSACTION;")

Semian[:mysql_testing].acquire do
@adapter.execute("COMMIT;")
@adapter.execute("COMMIT")
end
end

Expand All @@ -334,23 +334,24 @@ def test_query_allowlisted_returns_false_for_binary_sql

def test_semian_allows_release_savepoint
@adapter.execute("START TRANSACTION;")
@adapter.execute("SAVEPOINT active_record_2;")

Semian[:mysql_testing].acquire do
@adapter.execute("RELEASE SAVEPOINT active_record_99;")
@adapter.execute("RELEASE SAVEPOINT active_record_2")
end

@adapter.execute("ROLLBACK;")
end

def test_semian_allows_rollback_to_savepoint
@adapter.execute("START TRANSACTION;")
@adapter.execute("SAVEPOINT active_record_99;")
@adapter.execute("SAVEPOINT active_record_1;")

Semian[:mysql_testing].acquire do
@adapter.execute("ROLLBACK TO SAVEPOINT active_record_99;")
@adapter.execute("ROLLBACK TO SAVEPOINT active_record_1")
end

@adapter.execute("ROLLBACK;")
@adapter.execute("ROLLBACK")
end

def test_changes_timeout_when_half_open_and_configured
Expand Down

0 comments on commit 8e73b3d

Please sign in to comment.