pingcap / pingcap/tidb

SELECT INTO OUTFILE LINES STARTING BY is parsed but silently ignored, producing unprefixed output

Open
#70,984 1 comment 0 reactions 0 assignees View on GitHub
affects-9.0 component/executor found-by-ai may-affects-25.10 may-affects-26.3 severity/moderate sig/execution type/bug
Dominant language
Go
Stars
40.5k
Forks
6.2k
PR merge metrics
PR metrics pending

Description

## Bug Report

Please answer these questions before submitting your issue. Thanks!

### 1. Minimal reproduce step (Required)

```sql
CREATE TABLE t (id INT PRIMARY KEY, v VARCHAR(20));
INSERT INTO t VALUES (1,'x'),(2,'y');

-- MySQL 8.3 reference: every line starts with PREFIX.
SELECT * FROM t INTO OUTFILE '/tmp/mysql_start_by.tsv'
FIELDS TERMINATED BY ','
LINES STARTING BY 'PREFIX' TERMINATED BY '\n';
-- oracle bytes: 50 52 45 46 49 58 31 2c 78 0a 50 52 45 46 49 58 32 2c 79 0a
-- text:
-- PREFIX1,x
-- PREFIX2,y

-- TiDB on a514: statement succeeds, file exists, but no line has PREFIX.
SELECT * FROM t INTO OUTFILE '/tmp/tidb_start_by.tsv'
FIELDS TERMINATED BY ','
LINES STARTING BY 'PREFIX' TERMINATED BY '\n';
-- actual bytes: 31 2c 78 0a 32 2c 79 0a
-- text:
-- 1,x
-- 2,y
```

Probe output:

```text
BASELINE_TIDB_PLAIN_OK=True
BASELINE_MYSQL_PLAIN_OK=True
MYSQL_START_HEX=505245464958312c780a505245464958322c790a
MYSQL_ORACLE_PREFIX_OK
TIDB_TRIGGER_WRITE_OK
TIDB_START_HEX=312c780a322c790a
TIDB_LINE_COUNT=2
TIDB_PREFIXED_LINE_COUNT=0
TIDB_PREFIX_MISSING
TIDB_EXPORT_DIFFERS_MYSQL
```

The plain `LINES TERMINATED BY '\n'` control matches on both engines (`312c780a322c790a`), so the outfile path works and the defect is specifically the parsed `LINES STARTING BY` clause. The TiDB statement returns success with no warning.

### 2. What did you expect to see? (Required)

Prepend `s.LinesStartingBy` to each output line in `SelectIntoExec.dumpToOutfile` before the first field, matching MySQL semantics. If the clause is intentionally unsupported, reject it in the parser/planner before the file is opened. Add a regression test that compares the bytes with MySQL for `LINES STARTING BY 'PREFIX' TERMINATED BY '\n'`, plus the plain `LINES TERMINATED BY '\n'` control.

### 3. What did you see instead (Required)

Plain control on both engines: TIDB_PLAIN_HEX=312c780a322c790a, MYSQL_PLAIN_HEX=312c780a322c790a. MySQL 8.3 oracle with LINES STARTING BY: MYSQL_START_HEX=505245464958312c780a505245464958322c790a. TiDB with the same clause: TIDB_START_HEX=312c780a322c790a, TIDB_PREFIXED_LINE_COUNT=0, TIDB_PREFIX_MISSING; the statement returned success with no warning.

### 4. What is your TiDB version? (Required)

```text
Release Version: v8.4.0-this-is-a-placeholder
Edition: Community
Git Commit Hash: None
Git Branch: None
UTC Build Time: None
GoVersion: go1.25.12
Race Enabled: false
Check Table Before Drop: false
Store: unistore
Kernel Type: Classic
```

Built from source commit `a514a92784c9654502686e6ee6efc9e0aeda8afa` (pingcap/tidb master, 2026-09-07).

### 5. Root cause (optional)

- pkg/parser/parser.y:16478-16489 LINES STARTING BY production stores ast.LinesClause.Starting
- pkg/planner/core/common_plans.go:577-607 NewLineFieldsInfo copies linesInfo.Starting into LineFieldsInfo.LinesStartingBy
- pkg/planner/core/planbuilder.go:5923 SelectInto plan builder passes LineFieldsInfo to SelectIntoExec
- pkg/executor/select_into.go:124-215 dumpToOutfile appends FieldsTerminatedBy and LinesTerminatedBy but never LinesStartingBy

Contributor guide

Open the contributing guide

Research direction

Start in pkg/executor/select_into.go at dumpToOutfile, then trace LinesStartingBy through pkg/planner/core/common_plans.go and pkg/planner/core/planbuilder.go. Run the supplied SQL reproduction and add a regression test covering both LINES STARTING BY and the plain terminator control. Done means TiDB's exported bytes match the MySQL result while the plain control remains unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, mysql
Domain
databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.