Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sqlparse/keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@
(r'(?![_A-ZÀ-Ü])-?(\d+(\.\d*)|\.\d+)(?![_A-ZÀ-Ü])',
tokens.Number.Float),
(r'(?![_A-ZÀ-Ü])-?\d+(?![_A-ZÀ-Ü])', tokens.Number.Integer),
(r"'(''|\\'|[^'])*'", tokens.String.Single),
(r"'(''|\\'|\\\\|[^'])*'", tokens.String.Single),
# not a real string literal in ANSI SQL:
(r'"(""|\\"|[^"])*"', tokens.String.Symbol),
(r'"(""|\\"|\\\\|[^"])*"', tokens.String.Symbol),
(r'(""|".*?[^\\]")', tokens.String.Symbol),
Comment thread
RamiNoodle733 marked this conversation as resolved.
# sqlite names can be escaped with [square brackets]. left bracket
# cannot be preceded by word character or a right bracket --
Expand Down
28 changes: 28 additions & 0 deletions tests/test_issue_814.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from sqlparse import lexer
from sqlparse import tokens as T


def test_escaped_backslashes_single_quoted_token_stream():
tokens = list(lexer.tokenize(r"SELECT '\\', '\\'"))

assert tokens == [
(T.Keyword.DML, "SELECT"),
(T.Whitespace, " "),
(T.String.Single, r"'\\'"),
(T.Punctuation, ","),
(T.Whitespace, " "),
(T.String.Single, r"'\\'"),
]


def test_escaped_backslashes_double_quoted_token_stream():
tokens = list(lexer.tokenize(r'SELECT "\\", "\\"'))

assert tokens == [
(T.Keyword.DML, "SELECT"),
(T.Whitespace, " "),
(T.String.Symbol, r'"\\"'),
(T.Punctuation, ","),
(T.Whitespace, " "),
(T.String.Symbol, r'"\\"'),
]
15 changes: 15 additions & 0 deletions tests/test_tokenize.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,21 @@ def test_single_quotes():
assert repr(p.tokens[0])[:len(tst)] == tst


def test_single_quotes_escaped_backslash():
# issue 814 - Incorrect Tokenization of Escaped Backslashes
# A string containing an escaped backslash (\\) should be tokenized
# as a single string literal, not split incorrectly.
sql = r"SELECT '\\', '\\'"
tokens = list(lexer.tokenize(sql))
# Should be: SELECT, ws, '\\', ,, ws, '\\'
assert tokens[0] == (T.Keyword.DML, 'SELECT')
assert tokens[1] == (T.Whitespace, ' ')
assert tokens[2] == (T.String.Single, "'\\\\'")
assert tokens[3] == (T.Punctuation, ',')
assert tokens[4] == (T.Whitespace, ' ')
assert tokens[5] == (T.String.Single, "'\\\\'")
Comment thread
RamiNoodle733 marked this conversation as resolved.


def test_tokenlist_first():
p = sqlparse.parse(' select foo')[0]
first = p.token_first()
Expand Down