gh-133439: Fix dot commands with trailing spaces are mistaken for multi-line sqlite statements in the sqlite3 command-line interface (GH-133440)

This commit is contained in:
Tan Long 2025-05-09 19:41:10 +08:00 committed by GitHub
parent 5044e85265
commit ebd4881db2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 53 additions and 11 deletions

View file

@ -48,14 +48,22 @@ class SqliteInteractiveConsole(InteractiveConsole):
Return True if more input is needed; buffering is done automatically. Return True if more input is needed; buffering is done automatically.
Return False if input is a complete statement ready for execution. Return False if input is a complete statement ready for execution.
""" """
match source: if not source or source.isspace():
case ".version": return False
if source[0] == ".":
match source[1:].strip():
case "version":
print(f"{sqlite3.sqlite_version}") print(f"{sqlite3.sqlite_version}")
case ".help": case "help":
print("Enter SQL code and press enter.") print("Enter SQL code and press enter.")
case ".quit": case "quit":
sys.exit(0) sys.exit(0)
case _: case "":
pass
case _ as unknown:
self.write("Error: unknown command or invalid arguments:"
f' "{unknown}".\n')
else:
if not sqlite3.complete_statement(source): if not sqlite3.complete_statement(source):
return True return True
execute(self._cur, source) execute(self._cur, source)

View file

@ -116,6 +116,38 @@ class InteractiveSession(unittest.TestCase):
self.assertEqual(out.count(self.PS2), 0) self.assertEqual(out.count(self.PS2), 0)
self.assertIn(sqlite3.sqlite_version, out) self.assertIn(sqlite3.sqlite_version, out)
def test_interact_empty_source(self):
out, err = self.run_cli(commands=("", " "))
self.assertIn(self.MEMORY_DB_MSG, err)
self.assertEndsWith(out, self.PS1)
self.assertEqual(out.count(self.PS1), 3)
self.assertEqual(out.count(self.PS2), 0)
def test_interact_dot_commands_unknown(self):
out, err = self.run_cli(commands=(".unknown_command", ))
self.assertIn(self.MEMORY_DB_MSG, err)
self.assertEndsWith(out, self.PS1)
self.assertEqual(out.count(self.PS1), 2)
self.assertEqual(out.count(self.PS2), 0)
self.assertIn("Error", err)
# test "unknown_command" is pointed out in the error message
self.assertIn("unknown_command", err)
def test_interact_dot_commands_empty(self):
out, err = self.run_cli(commands=("."))
self.assertIn(self.MEMORY_DB_MSG, err)
self.assertEndsWith(out, self.PS1)
self.assertEqual(out.count(self.PS1), 2)
self.assertEqual(out.count(self.PS2), 0)
def test_interact_dot_commands_with_whitespaces(self):
out, err = self.run_cli(commands=(".version ", ". version"))
self.assertIn(self.MEMORY_DB_MSG, err)
self.assertEqual(out.count(sqlite3.sqlite_version + "\n"), 2)
self.assertEndsWith(out, self.PS1)
self.assertEqual(out.count(self.PS1), 3)
self.assertEqual(out.count(self.PS2), 0)
def test_interact_valid_sql(self): def test_interact_valid_sql(self):
out, err = self.run_cli(commands=("SELECT 1;",)) out, err = self.run_cli(commands=("SELECT 1;",))
self.assertIn(self.MEMORY_DB_MSG, err) self.assertIn(self.MEMORY_DB_MSG, err)

View file

@ -0,0 +1,2 @@
Fix dot commands with trailing spaces are mistaken for multi-line SQL
statements in the sqlite3 command-line interface.