Files
greptimedb/tests
dennis zhuang 7cbd20a053 fix(mysql): strip leading comments before the federated statement filter (#9156)
* fix(mysql): strip leading comments before the federated statement filter

JDBC clients prefix every statement with a comment. DataGrip sends
`/* ApplicationName=DataGrip <version> */` in front of each one, and every
pattern in the federated filter is anchored with `^`, so the prefix makes all
of them miss.

Two failures follow. `SET TRANSACTION READ WRITE` reaches the SQL parser and is
rejected. Worse, the DBeaver-specific entries such as
`^(/\* ApplicationName=(.*)SELECT @@(.*))` do match DataGrip's prefix, so
`SELECT @@GLOBAL.event_scheduler` and `SHOW VARIABLES LIKE ...` are absorbed
into a zero-column output, which the MySQL writer sends as an OK packet. The
JDBC driver reports that the statement returned no cursor.

Strip leading whitespace and comments before matching, and drop the
ApplicationName-specific entries the stripping makes redundant. The three that
had no unprefixed counterpart (`SHOW PLUGINS`, `SHOW ENGINES`, `SHOW @@...`)
keep their behaviour as plain patterns.

Also covers gaps found while probing the same path:

- `BEGIN` is absorbed like `START TRANSACTION`/`COMMIT`/`ROLLBACK`.
- `SHOW [GLOBAL|SESSION|LOCAL] VARIABLES|STATUS` parses; the scope is ignored
  because GreptimeDB keeps no global/session split.
- `USER()`, `CURRENT_USER()`, `SYSTEM_USER()` and `SCHEMA()` are registered.

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

* fix(mysql): keep executable comments, reject multi-statement absorption

Review follow-up on the comment stripping, plus the remaining MySQL
compatibility gaps from #9155.

`/*!...*/` is an executable comment: mysqldump emits its initialization as
`/*!40101 SET NAMES ... */`, and the patterns match those verbatim. Stripping
it left an empty statement, so nothing matched and the original SQL reached the
parser, which rejects `SetNames` and `MultipleAssignments`. Leave executable
comments in place.

Absorbing a request also has to stop at a statement boundary, because every
pattern ends in `(.*)`. `BEGIN; INSERT INTO t VALUES (1)` used to fail on the
unsupported `BEGIN`; once `BEGIN` became absorbable the whole request would
report success and write nothing. A request is now scanned for a second
statement and handed to the query engine if it has one. The scan skips plain
comments and string literals so a `;` inside either is not a boundary, and
treats a `/*!...*/` that is not the request itself as a statement, since it
carries SQL.

`check()` now dispatches on the leading statement keyword, so INSERT, UPDATE,
CREATE and ordinary SELECTs run no regex at all — this replaces the narrower
hand-rolled INSERT shortcut. The statement scan runs only for a request the
patterns already matched, which is always a short one.

New compatibility surface:

- `SELECT CURRENT_USER|SESSION_USER|SYSTEM_USER|USER` without parentheses, and
  `SELECT @var`, are answered here rather than in the parser. Both are anchored
  to the whole statement, so `SELECT user FROM t` still reads the column.
- `information_schema.plugins`, `user_privileges` and `processlist` are
  registered as empty tables, like the other MySQL-shape tables around them.
  Sessions are reported through `information_schema.process_list` and
  `SHOW PROCESSLIST`; `processlist` carries the column shape only.

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>

---------

Signed-off-by: Dennis Zhuang <killme2008@gmail.com>
2026-09-15 08:59:30 +00:00
..

Sqlness Test

Sqlness manual

Case file

Sqlness has two types of file:

  • .sql: test input, SQL only
  • .result: expected test output, SQL and its results

.result is the output (execution result) file. If you see .result files is changed, it means this test gets a different result and indicates it fails. You should check change logs to solve the problem.

You only need to write test SQL in .sql file, and run the test.

Case organization

The root dir of input cases is tests/cases. It contains several subdirectories stand for different test modes. E.g., standalone/ contains all the tests to run under greptimedb standalone start mode.

Under the first level of subdirectory (e.g. the cases/standalone), you can organize your cases as you like. Sqlness walks through every file recursively and runs them.

Kafka WAL

Sqlness supports Kafka WAL. You can either provide a Kafka cluster or let sqlness to start one for you.

To run test with kafka, you need to pass the option -w kafka. If no other options are provided, sqlness will use conf/kafka-cluster.yml to start a Kafka cluster. This requires docker and docker-compose commands in your environment.

Otherwise, you can additionally pass the your existing kafka environment to sqlness with -k option. E.g.:

cargo sqlness bare -w kafka -k localhost:9092

In this case, sqlness will not start its own kafka cluster and the one you provided instead.

Run the test

Unlike other tests, this harness is in a binary target form. You can run it with:

cargo sqlness bare

It automatically finishes the following procedures: compile GreptimeDB, start it, grab tests and feed it to the server, then collect and compare the results. You only need to check if the .result files are changed. If not, congratulations, the test is passed 🥳!