Skip to content

Commit f6de3db

Browse files
author
James William Pye
committed
Simplify syntax error output.
Just show the line that it occurred on and mark the relative position.
1 parent b138be5 commit f6de3db

2 files changed

Lines changed: 23 additions & 21 deletions

File tree

postgresql/documentation/changes.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
* Implement query libraries and connection categories[#1010581 & #1010618].
1414
* Implement ``clone()`` on Connections, Statements, and Cursors.
1515
* Refactor ``ps.load()`` into ``ps.load_chunks()`` and ``ps.load_rows()``.
16-
* Performance optimizations.
16+
* Display the line and mark the location of the POSITION for syntax errors.
17+
* Performance improvements.
1718
* Refactor `postgresql.api.InterfaceElement`.
1819
* Refactor driver.pq3.Connection to use protocol.client3.Connection.
1920
* Refactor driver.pq3.Cursor into types selected by PreparedStatements.

postgresql/driver/pq3.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -622,36 +622,37 @@ def _e_metas(self):
622622
pos = int(pos)
623623
# get the statement source
624624
q = str(self.string)
625-
#lineno = q.count('\n', pos)
626-
# tabs before position
627-
tabs = q.count('\t', 0, pos)
625+
# normalize position..
626+
pos = len('\n'.join(q[:pos].splitlines()))
627+
# normalize newlines
628+
q = '\n'.join(q.splitlines())
629+
line_no = q.count('\n', 0, pos) + 1
628630
# replace tabs with spaces because there is no way to identify
629631
# the tab size of the final display. (ie, marker will be wrong)
630-
q = q.replace('\t', ' ')
631-
# adjust position for the tab substitution
632-
pos = pos + (3 * tabs)
632+
q = q.replace('\t', ' ')
633633
# grab the relevant part of the query string.
634634
# the full source will be printed elsewhere.
635-
bov = max(pos-80, 0)
636-
view = q[bov:pos+80]
635+
# beginning of string or the newline before the position
636+
bov = q.rfind('\n', 0, pos) + 1
637+
print(bov)
638+
# end of string or the newline after the position
639+
eov = q.find('\n', pos)
640+
if eov == -1:
641+
eov = len(q)
642+
view = q[bov:eov]
637643
# position relative to the beginning of the view
638-
pos = max(pos-bov, 0)
644+
pos = pos-bov
639645
# analyze lines prior to position
640-
lines = view[:pos].splitlines()
641-
line_no = len(lines)
642-
line_pos = len(lines[-1]) - 1
643646
dlines = view.splitlines()
644-
marker = (line_pos * ' ') + '^'
645-
marker = marker + ('-' * ((len(dlines[max(line_no-1,0)]) - len(marker))+10))
646-
marker += '(point of error)-<<<<<<<'
647+
marker = ((pos-1) * ' ') + '^' + (
648+
' [line %d, character %d] ' %(line_no, pos)
649+
)
647650
# insert marker
648-
dlines.insert(line_no, marker)
649-
dlines.insert(0, '-'*20)
650-
dlines.append('-'*20)
651-
yield ('SYNTAX ERROR', os.linesep.join(('|- ' + x for x in dlines)))
651+
dlines.append(marker)
652+
yield ('LINE', os.linesep.join(dlines))
652653
except:
653654
import traceback
654-
traceback.print_exc()
655+
yield ('LINE', traceback.format_exc(chain=False))
655656
spt = self.sql_parameter_types
656657
if spt is not None:
657658
yield ('sql_parameter_types', spt)

0 commit comments

Comments
 (0)