Skip to content

fix: handle trailing SQL comments in multiline submit#1

Open
bobo-xxx wants to merge 1 commit intomainfrom
clawoss/fix-trailing-sql-comments
Open

fix: handle trailing SQL comments in multiline submit#1
bobo-xxx wants to merge 1 commit intomainfrom
clawoss/fix-trailing-sql-comments

Conversation

@bobo-xxx
Copy link
Copy Markdown
Owner

Fixes two related bugs when a SQL comment follows the semicolon:

Bug 1 — pgbuffer._is_complete(): sql.endswith(';') returned False when a trailing comment followed the semicolon. In multiline mode, pressing Enter never submitted the query.

Bug 2 — pgexecute.run(): sql.rstrip(';') couldn't strip the semicolon because the string ended with comment text. The malformed SQL was sent to PostgreSQL via psycopg's extended query protocol.

Both locations now use sqlparse.format(sql, strip_comments=True) before checking for / removing the trailing semicolon.

Fixes dbcli#1559

Fixes two related bugs when a SQL comment follows the semicolon:
- pgbuffer._is_complete(): sql.endswith(';') returned False when a trailing
  comment followed the semicolon. In multiline mode, pressing Enter never
  submitted the query.
- pgexecute.run(): sql.rstrip(';') couldn't strip the semicolon because
  the string ended with comment text. The malformed SQL was sent to
  PostgreSQL via psycopg's extended query protocol.

Both locations now use sqlparse.format(sql, strip_comments=True) before
checking for / removing the trailing semicolon.
Copilot AI review requested due to automatic review settings April 18, 2026 08:47
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes multiline submission and execution issues when a SQL statement terminator (;) is followed by a trailing SQL comment, by normalizing SQL before semicolon checks/stripping.

Changes:

  • Update PGExecute.run() to strip comments before attempting to remove a trailing semicolon.
  • Update pgbuffer._is_complete() to ignore comments when determining whether input is “complete” (ends with ;).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
pgcli/pgexecute.py Alters per-statement cleanup to handle semicolons followed by trailing comments before execution.
pgcli/pgbuffer.py Adjusts multiline completeness detection to treat ; as terminal even when followed by comments.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pgcli/pgexecute.py
Comment on lines 363 to 365
# Remove spaces, eol and semi-colons.
sql = sql.rstrip(";")
sql = sqlparse.format(sql, strip_comments=True).rstrip(";")
sql = sqlparse.format(sql, strip_comments=False).strip()
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change introduces new behavior around semicolon stripping with trailing comments, but there isn’t a test covering the specific case ...; -- trailing comment (or ...; /* trailing */) on the same line. Adding a regression test in tests/test_pgexecute.py would help ensure the query is executed successfully and that only the terminator semicolon is removed (not the comment content).

Copilot uses AI. Check for mistakes.
Comment thread pgcli/pgbuffer.py
Comment on lines +16 to +17
sql_for_check = sqlparse.format(sql, strip_comments=True)
return sql_for_check.endswith(";") and not is_open_quote(sql)
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sqlparse.format(sql, strip_comments=True) is likely to parse/rewrite the SQL and may leave trailing whitespace/newlines; using it without .strip()/.rstrip() can make endswith(';') unreliable. Also, this adds an additional sqlparse parse/format pass on top of is_open_quote(sql) (which already calls sqlparse.parse), and this Condition can be evaluated frequently in the UI; consider a cheaper approach (e.g., stripping only trailing comments/whitespace before checking for ;) to avoid performance regressions in multiline mode.

Copilot uses AI. Check for mistakes.
Comment thread pgcli/pgexecute.py
Comment on lines 361 to 365
# run each sql query
for sql in sqlarr:
# Remove spaces, eol and semi-colons.
sql = sql.rstrip(";")
sql = sqlparse.format(sql, strip_comments=True).rstrip(";")
sql = sqlparse.format(sql, strip_comments=False).strip()
Copy link

Copilot AI Apr 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sqlparse.format(sql, strip_comments=True) removes all SQL comments, not just the trailing comment after a semicolon. In this function you intentionally re-add leading comments (lines 355-360) so they show up in logs, but this change strips them back out and also drops any in-query comments/hints (which some users rely on for observability or extensions like pg_hint_plan). Consider using a comment-stripped copy only to locate/remove a trailing semicolon, while keeping the original SQL (including comments) for execution/logging.

Copilot uses AI. Check for mistakes.
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