Skip to content

Conversation

@sufleR
Copy link
Owner

@sufleR sufleR commented Dec 19, 2025

Problem

The prepared_for_logs method (used for logging SQL queries) was incorrectly normalizing whitespace inside SQL quoted strings. The previous implementation in prepare_query used a simple regex pattern gsub(/(\n|\s)+/, ' ') that would:

  1. Apply to the entire ERB template before rendering
  2. Corrupt string literals that contained whitespace
  3. Break multiline ERB code blocks (e.g., <% ... %>)

This caused issues with complex ERB templates that use multiline Ruby code blocks or contain SQL string literals with intentional whitespace.

Solution

This PR refactors the prepare_query method to:

  1. Render ERB first, then normalize whitespace on the resulting SQL
  2. Preserve quoted string content using a sophisticated regex that matches:
    • Single-quoted strings: '...'
    • Double-quoted strings: "..."
    • Whitespace outside quotes (which gets normalized)
  3. Only capture and replace whitespace that's not inside quotes

The new pattern /'(?:[^'\\]|\\.)*'|"(?:[^"\\]|\\.)*"|(\s+)/ properly handles:

  • Escaped quotes inside strings
  • Nested quotes
  • Multiline strings
  • ERB code blocks that span multiple lines

Changes

  • lib/sql_query.rb: Refactored prepare_query method with improved whitespace handling
  • spec/spec_helper.rb: Simplified database configuration for consistent local/CI testing
  • spec/sql_query_spec.rb: Added comprehensive tests for multiline ERB templates
  • spec/sql_queries/multiline_erb.sql.erb: New test fixture demonstrating multiline ERB usage

Why This Matters

This fix is critical because:

  1. Data Integrity: Prevents corruption of SQL string literals in logs
  2. Template Flexibility: Allows developers to use multiline ERB code blocks for cleaner, more maintainable SQL templates
  3. Debugging: Ensures logged SQL accurately represents what's being executed
  4. Backwards Compatible: Doesn't change behavior for simple templates, only fixes broken edge cases

Testing

All existing tests pass, plus new tests verify:

  • Multiline ERB blocks render correctly
  • Quoted strings with whitespace are preserved
  • Prepared logs still produce clean, single-line output
  • No syntax errors with complex ERB templates
bundle exec rspec
# 27 examples, 0 failures
# Line Coverage: 98.67%

…mplates

The previous implementation of prepare_query used a simple regex to normalize
whitespace, which incorrectly modified content inside SQL quoted strings when
preparing queries for logs. This caused issues with multiline ERB templates
where string literals could be corrupted.

Changes:
- Refactored prepare_query to render ERB first, then normalize whitespace
- Added regex pattern to match quoted strings and preserve their content
- Only whitespace outside of quotes is normalized to single spaces
- Simplified test database configuration to use consistent postgres setup
- Added test coverage for multiline ERB templates with quoted strings

This fix ensures that SQL string literals remain intact while still providing
clean, single-line output for logging purposes.
- Replace Perl-style backreference $1 with ::Regexp.last_match(1)
- Remove extra spacing before inline comment
@sufleR sufleR closed this Dec 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants