You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 066baeb
Browse filesBrowse the repository at this point in the historyBrowse files
feat: support MySQL CREATE TABLE LIKE and query sources
Extend native CREATE TABLE parsing beyond explicit column definitions.
Accept LIKE relation and (LIKE relation), preserving the source as a
structured qualified name without overwriting the destination table/schema
routing metadata. Normalize the parenthesized form to canonical LIKE.
Parse optional-AS query sources, optional IGNORE/REPLACE duplicate handling,
preceding table options and optional column definitions. Reuse the strict
query parser for SELECT, CTEs, set operations, parenthesized queries, TABLE,
VALUES ROW and supported locking clauses. Keep the source query traversable
and clonable rather than retaining an opaque SQL tail; emit canonical AS.
Distinguish grouped query sources from column lists, enforce native option
comma boundaries and reject mixed LIKE/definition/option/query forms. Match
the native duplicate REPLACE production by discarding its lexer-attached
hint payload while preserving hints belonging to the actual SELECT. Accept
native grammar-valid empty-definition CREATE forms while leaving their
no-columns rejection to server semantic validation. Append two AST kinds
and keep local execution and conservative parameterization guarded.
Add round-trip, source ownership, traversal, routing metadata, malformed
boundary and hint-position regressions. Expand the hand-reduced corpus by
49 cases, with official grammar anchors in both pinned MySQL releases.
Native checking discovered that CREATE SELECT INTO OUTFILE is valid but
still rejected by the strict query-source parser: record it as a valid
known gap with expected ERROR, not a malformed control. Update documentation
with that limit and the remaining partition/specialized DDL exclusions.
Validation: forced full rebuild and make test pass 1,674 tests with 37
external-database skips. ASan/UBSan with leak detection passes 158 focused
MySQL tests. All 434 curated expectations match: 213 CHECKED, 220 REJECTED
and one explicitly expected valid-query gap; 661 source anchors verify per
release. Native 8.4.8 and 9.7.2 have zero intended-validity mismatches, and
all 213 emitted positives retain native state/error codes. Semantic errors
remain separately unresolved. Independent review verifies the REPLACE hint
fix and reports no remaining substantive findings. Benchmark artifacts are
excluded from this commit.
Copy file name to clipboardExpand all lines: docs/mysql-compatibility.md
+5-3Lines changed: 5 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,9 @@ The five previously tracked witnesses—`JSON_TABLE`, `CREATE TABLE`, `ALTER TAB
6
6
7
7
`JSON_TABLE` retains separate document, path, column-list, column, nested-path, and response nodes. Supported columns include `FOR ORDINALITY`, typed `PATH`, `EXISTS PATH`, and recursive `NESTED PATH ... COLUMNS` with a limit of 128 column-list levels. Both pinned grammars require `PATH` after `NESTED`. Paths use native text literals, including national/charset prefixes and adjacent quoted fragments. `NULL`, `ERROR`, and `DEFAULT` responses preserve `ON EMPTY` and `ON ERROR` in either native order; the reversed order is deprecated by MySQL. DEFAULT uses the native signed-literal production, including numeric, text, temporal, hex, and bit literals. A table alias is required, and an alias-column list is not accepted. The [8.4.8 JSON_TABLE productions](https://github.com/mysql/mysql-server/blob/0896fcd61dec11a0904166911a0126f59daaa1bf/sql/sql_yacc.yy#L12023) and [9.7.2 JSON_TABLE productions](https://github.com/mysql/mysql-server/blob/008e09c2834b98143a8c067d4d225c90953050cf/sql/sql_yacc.yy#L12447) define this bounded grammar coverage. JSON path validity and conversion semantics remain native semantic checks.
8
8
9
-
MySQL table DDL preserves structured definitions, constraints, options, and ALTER actions. The supported subset includes column types and attributes, generated/default expressions, common keys, CHECK and foreign-key constraints, common table options, and ADD/DROP/MODIFY/CHANGE/RENAME actions. TEMPORARY and IF NOT EXISTS are supported for CREATE TABLE. Shared native type parsing also serves JSON_TABLE columns and procedure parameters; VECTOR is a 9.7 type and is not part of the 8.4 grammar. CREATE TABLE LIKE, query-derived table definitions, partitioning, and specialized index/table options remain outside this bounded implementation. Unknown or incomplete clauses are rejected rather than retained as unvalidated tails. The corpus anchors [8.4.8 CREATE TABLE](https://github.com/mysql/mysql-server/blob/0896fcd61dec11a0904166911a0126f59daaa1bf/sql/sql_yacc.yy#L3217) and [9.7.2 CREATE TABLE](https://github.com/mysql/mysql-server/blob/008e09c2834b98143a8c067d4d225c90953050cf/sql/sql_yacc.yy#L3317), plus the ALTER and definition productions used by each witness.
9
+
MySQL table DDL preserves structured definitions, constraints, options, and ALTER actions. The supported subset includes column types and attributes, generated/default expressions, common keys, CHECK and foreign-key constraints, common table options, and ADD/DROP/MODIFY/CHANGE/RENAME actions. TEMPORARY and IF NOT EXISTS are supported for CREATE TABLE. Shared native type parsing also serves JSON_TABLE columns and procedure parameters; VECTOR is a 9.7 type and is not part of the 8.4 grammar. CREATE TABLE LIKE and query-derived definitions are supported as described below. Partitioning and specialized index/table options remain outside this bounded implementation. Unknown or incomplete clauses are rejected rather than retained as unvalidated tails. The corpus anchors [8.4.8 CREATE TABLE](https://github.com/mysql/mysql-server/blob/0896fcd61dec11a0904166911a0126f59daaa1bf/sql/sql_yacc.yy#L3217) and [9.7.2 CREATE TABLE](https://github.com/mysql/mysql-server/blob/008e09c2834b98143a8c067d4d225c90953050cf/sql/sql_yacc.yy#L3317), plus the ALTER and definition productions used by each witness.
10
+
11
+
CREATE TABLE accepts both `LIKE source` and `(LIKE source)`, retaining a structured source relation separately from the target name/schema metadata. Emission normalizes the parenthesized form to `LIKE source`. Query-derived tables accept optional `AS`, optional `IGNORE` or `REPLACE`, optional column definitions and preceding table options. The source is a traversable query AST, including CTEs, set operations, grouped queries, TABLE and VALUES ROW sources, hints and supported locking clauses. Emission adds canonical `AS`. A hint attached to duplicate-handling REPLACE is ignored as in the native grammar; a SELECT hint is preserved. Commas separate table options and cannot precede the query. LIKE cannot be combined with definitions, options or a query suffix. Bare CREATE TABLE and option-only forms are syntactically native but encounter the server's no-columns semantic error. CTAS with `SELECT ... INTO OUTFILE` is accepted by both native pins but remains an explicitly tracked gap in the strict query-source parser. Local execution and parameterization remain guarded for all CREATE forms.
10
12
11
13
`CREATE PROCEDURE` preserves typed IN/OUT/INOUT parameters, SQL-language routine characteristics, a single supported query/DML/SET statement or a BEGIN/END body, and nested blocks up to 64 levels. Statement separators inside supported bodies remain part of the procedure AST, including when parsing a batch. This grouping guarantee does not extend to unsupported or malformed routine bodies: the batch parser can stop at an inner semicolon and reports a failed batch. Local and user-variable SET assignments are supported. CREATE DEFINER, procedure IF NOT EXISTS, non-SQL languages, DECLARE, labels, conditionals, loops, cursors, handlers, and scoped/session-configuration SET forms remain unsupported. These broader native constructs are not labeled malformed merely because ParserSQL rejects them. The corpus records [8.4.8 procedure productions](https://github.com/mysql/mysql-server/blob/0896fcd61dec11a0904166911a0126f59daaa1bf/sql/sql_yacc.yy#L17938) and [9.7.2 procedure productions](https://github.com/mysql/mysql-server/blob/008e09c2834b98143a8c067d4d225c90953050cf/sql/sql_yacc.yy#L18697), including parameter, characteristic, and block productions.
12
14
@@ -72,7 +74,7 @@ Malformed controls are handled separately: a complete AST is `MALFORMED_ACCEPTED
72
74
73
75
Every fixture freezes one exact expected outcome. Known gaps do not make arbitrary failures acceptable. Both regression and unexpected improvement cause exit status 1, so a fixed gap must be reviewed and explicitly promoted in the corpus. When promoting, add an independently derived `expected_sql`, set `known_gap=false`, and require `CHECKED`. Harness/transport/source errors return 2. Exit status 0 means the expected baseline matched, including its documented known gaps.
74
76
75
-
The 385-case curated baseline has 192`CHECKED` witnesses and 193 `REJECTED` malformed controls, with no remaining `known_gap` records. All five previously tracked gaps are promoted. Source verification checks 465 exact grammar anchors per pinned release. These counts describe this selected corpus only, not overall dialect coverage.
77
+
The 434-case curated baseline has 213`CHECKED` witnesses, 220 `REJECTED` malformed controls, and one valid native CTAS/INTO witness with the expected `ERROR` outcome. All five original tracked gaps remain promoted; the expanded corpus now records the newly discovered CTAS/INTO gap explicitly. Source verification checks 661 exact grammar anchors per pinned release. These counts describe this selected corpus only, not overall dialect coverage.
76
78
77
79
The JSON report includes all original and reparsed records, source verification counts, pinned revisions, SQL-mode metadata, and SHA-256 hashes of the corpus and probe. Counts apply only to these witnesses. The probe uses hex-line input and hex fields in its TSV response, preserving tabs, newlines and embedded NUL bytes. It emits while both the input string and parser arena are alive; Python reparses owned copies in a second probe invocation.
78
80
@@ -91,7 +93,7 @@ Each curated case explicitly chooses direct query execution, `EXPLAIN` for DML (
91
93
92
94
Native results are stored separately in `native_oracle`: `ACCEPTED`, `SYNTAX_REJECTED` (1064/1149), `SERVER_ERROR`, `CLIENT_ERROR`, or **NOT VERIFIED**. For example, a derived table missing its required alias returns error 1248, and the corresponding JSON_TABLE witness returns 3667; these remain server errors, even though the corpus requires ParserSQL to reject those inputs. Accepted invalid controls and syntax-rejected valid controls count as expectation mismatches, using per-version validity when specified. Server errors remain explicitly unresolved; client errors return status 2. Thus exit status 0 still does not mean all native cases were verified. The default corpus metadata remains **NOT VERIFIED**, while the optional report describes the actual native observations.
93
95
94
-
Native checks of all 385 witnesses under `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION` found no intended-validity mismatches. MySQL 8.4.8 accepted 170, syntax-rejected 198, and returned 17 server errors; MySQL 9.7.2 accepted 175, syntax-rejected 188, and returned 22 server errors. Every case had a native action, including DDL and procedure creation; no cases were skipped, and all owned schemas were cleaned up. Semantic errors remain unresolved observations, including missing aliases, unsupported runtime features, engine prerequisites, and error 1235 for the grammar-valid procedure parameter `COLLATE BINARY` witness in both releases. These must not be relabeled as syntax rejection. Reports are intentionally kept outside the repository; rerun each isolated socket to reproduce current observations. Separate native runs also submitted all 192 valid emitted witnesses to each pinned server. Every emitted statement retained the original observation state and error code. This is a bounded additional emission check, not proof of AST, optimizer, result-value, or execution equivalence.
96
+
Native checks of all 434 witnesses under `ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION` found no intended-validity mismatches. MySQL 8.4.8 accepted 190, syntax-rejected 225, and returned 19 server errors; MySQL 9.7.2 accepted 195, syntax-rejected 215, and returned 24 server errors. Every case had a native action, including DDL and procedure creation; no cases were skipped, and all owned schemas were cleaned up. Semantic errors remain unresolved observations, including missing aliases, CREATE TABLE with no columns, unsupported runtime features, engine prerequisites, and error 1235 for the grammar-valid procedure parameter `COLLATE BINARY` witness in both releases. These must not be relabeled as syntax rejection. Reports are intentionally kept outside the repository; rerun each isolated socket to reproduce current observations. Separate native runs also submitted all 213 successfully parsed valid emitted witnesses to each pinned server. Every emitted statement retained the original observation state and error code. This is a bounded additional emission check, not proof of AST, optimizer, result-value, or execution equivalence.
95
97
96
98
The corpus is deliberately selected and is not a representative workload. It includes shared and explicitly version-specific witnesses; this does not imply identical dialects in 8.4.8 and 9.7.2. The version-specific entries record `applicability`, source productions for both versions, `native_validity` per version, and observed native outcomes. Their generic `validity=valid` denotes the 9.7.2 grammar target. The native helper selects the intended validity using the actual server version, so an expected 8.4.8 syntax rejection is not treated as a corpus error. Stored native observations are context, not substitutes for a current run. These version-specific query additions now pass ParserSQL parse/emission/reparse checks; native runtime restrictions remain separately reported. The following differences include the original four query witnesses and two separate DDL spot checks:
0 commit comments