Skip to content

feat(mysql): expose executable comment recognition - #398

Open
fujiabao89 wants to merge 2 commits into
bytebase:mainfrom
fujiabao89:codex/mysql-executable-comment-api
Open

feat(mysql): expose executable comment recognition#398
fujiabao89 wants to merge 2 commits into
bytebase:mainfrom
fujiabao89:codex/mysql-executable-comment-api

Conversation

@fujiabao89

@fujiabao89 fujiabao89 commented Jul 30, 2026

Copy link
Copy Markdown

Summary

  • add parser.ContainsExecutableComment(sql, options) as a one-shot public lexer API
  • require callers to provide the session's NO_BACKSLASH_ESCAPES mode through ExecutableCommentOptions
  • mark /*! ... */ at the lexer boundary without changing normal token or AST behavior
  • stop detection at the first executable-comment opener, before any splice
  • cover the 12 positive and 5 negative cases from Feature request: Public API for MySQL executable comment (/*!...*/) recognition #397, plus SQL-mode, control-whitespace, invalid-version, unterminated, and no-splice cases

Why

MySQL executable comments are spliced into the token stream today, so callers cannot distinguish their contents from ordinary SQL through the public API. Security-sensitive consumers need a stable lexer signal instead of regex or raw-text scanning.

The API is intentionally conservative: unknown version prefixes and unterminated executable comments return true, while string literals, quoted identifiers, ordinary block comments, optimizer hints, and line comments return false under the supplied SQL mode.

Closes #397.

Validation

  • go build ./mysql/...
  • go test -short ./mysql/parser -count=1
  • go test -short ./mysql/ast ./mysql/completion ./mysql/deparse ./mysql/parser ./mysql/validate -count=1
  • go vet ./mysql/parser

The Docker-backed non-short Oracle/catalog tests cannot run in the local Windows environment; the relevant non-container packages pass.

@fujiabao89
fujiabao89 marked this pull request as ready for review July 30, 2026 06:03
@fujiabao89
fujiabao89 requested a review from rebelice as a code owner July 30, 2026 06:03

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fee6348234

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread mysql/parser/executable_comment.go Outdated
Comment thread mysql/parser/executable_comment.go Outdated
Comment thread mysql/parser/lexer.go

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a5c1a85a6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +5 to +8
type ExecutableCommentOptions struct {
// NoBackslashEscapes must match the session's NO_BACKSLASH_ESCAPES SQL
// mode. When true, backslashes in string literals are ordinary bytes.
NoBackslashEscapes bool

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Account for ANSI_QUOTES when scanning double quotes

When the session enables ANSI_QUOTES without NO_BACKSLASH_ESCAPES, double quotes delimit identifiers and a backslash does not escape the following quote. For example, in SELECT "x\" /*!50000 + 1 */, MySQL closes the identifier before the comment and recognizes the executable opener, while this helper treats \" as part of a string and returns false. Add the applicable ANSI_QUOTES mode to the options and scan double-quoted identifiers with identifier escaping, or otherwise conservatively detect this boundary.

Useful? React with 👍 / 👎.

Comment thread mysql/parser/lexer.go
Comment on lines 1949 to +1950
if l.pos+2 < len(l.input) && l.input[l.pos+2] == '!' {
l.hasExecutableComment = true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Stop regular comments at MySQL's first terminator

Because this flag is set only after the ordinary-comment skipper exposes an opener, the skip logic's generic nesting behavior can hide a server-visible executable comment. MySQL regular block comments do not generally nest, so in /* outer /* inner */ /*!50000 DROP TABLE t*/ the first */ ends the ordinary comment and MySQL processes the following executable comment; this lexer instead increments its nesting depth for the inner /*, consumes through the executable comment's closing delimiter, and returns false. The detection path should scan ordinary comments using MySQL's actual termination rules.

Useful? React with 👍 / 👎.

Comment on lines +3 to +8
// ExecutableCommentOptions configures SQL modes that affect lexical comment
// recognition.
type ExecutableCommentOptions struct {
// NoBackslashEscapes must match the session's NO_BACKSLASH_ESCAPES SQL
// mode. When true, backslashes in string literals are ordinary bytes.
NoBackslashEscapes bool

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Make string scanning aware of the connection character set

With a multibyte connection character set whose trailing bytes may include 0x5c, the byte-oriented string scanner can mistake part of a character for a backslash escape and hide an active opener. For example, under sjis, the bytes in SELECT '\x95\x5c' /*!50000 DROP TABLE t*/ encode one character followed by the closing quote, so MySQL sees the executable comment; this lexer consumes that quote as escaped and returns false. Pass the connection character set into detection or conservatively handle backslashes that can be multibyte trailing bytes.

Useful? React with 👍 / 👎.

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.

Feature request: Public API for MySQL executable comment (/*!...*/) recognition

1 participant