From 572cbd1f819cf8e015541a06f0ecf1d75cd0cace Mon Sep 17 00:00:00 2001
From: Kieran Trezona-le Comte <trezona-lecomte@gmail.com>
Date: Fri, 17 Jul 2015 15:47:54 +1200
Subject: [PATCH] Truncate long "at or near ..." error messages

---
 TODO                 |  2 +-
 lib/sqlint/linter.rb |  6 +++++-
 spec/linter_spec.rb  | 11 ++++++++++-
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/TODO b/TODO
index e0db5ee..5a3bae3 100644
--- a/TODO
+++ b/TODO
@@ -6,4 +6,4 @@
 - [ ] Support for other SQL dialects
 - [ ] JSON output
 - [ ] Huge files
-- [ ] Maybe truncate long 'at or near "blah"' strings
+- [X] Maybe truncate long 'at or near "blah"' strings
diff --git a/lib/sqlint/linter.rb b/lib/sqlint/linter.rb
index 432383a..848cf6d 100644
--- a/lib/sqlint/linter.rb
+++ b/lib/sqlint/linter.rb
@@ -31,7 +31,7 @@ module SQLint
       rescue PgQuery::ParseError => e
         offset = e.location + parse_state.offset
         line_number, column_number = find_absolute_position(offset)
-        lint = Lint.new(@filename, line_number, column_number, :error, e.message)
+        lint = Lint.new(@filename, line_number, column_number, :error, clean_message(e.message))
 
         input_from_error = parse_state.input[e.location..-1]
         semicolon_pos = input_from_error.index(";") if input_from_error
@@ -54,5 +54,9 @@ module SQLint
       column_number = lines_before_error.any? ? lines_before_error.last.size : 1
       [line_number, column_number]
     end
+
+    def clean_message(message)
+      message.gsub(/(?<=at or near ")(.*)(?=")/) { |match| match[0..49] }
+    end
   end
 end
diff --git a/spec/linter_spec.rb b/spec/linter_spec.rb
index 941aa50..dc05c97 100644
--- a/spec/linter_spec.rb
+++ b/spec/linter_spec.rb
@@ -69,10 +69,19 @@ RSpec.describe SQLint::Linter do
 
     context "when there is a second error at the end of the file" do
       let(:input) { "WIBBLE; SELECT 1 FROM" }
-      it "report 2 errors" do
+      it "reports 2 errors" do
         expect(results).to eq([error(1, 1, WIBBLE_ERROR),
                                error(1, 21, "syntax error at end of input")])
       end
     end
   end
+
+  describe "long error messages" do
+    context "when the 'at or near' fragment is longer than 50 characters" do
+      let(:input) { "SELECT '" + 'x' * 100 }
+      it "truncates the fragment" do
+        expect(results).to eq([error(1, 8, "unterminated quoted string at or near \"'#{'x' * 49}\"")])
+      end
+    end
+  end
 end
-- 
GitLab