FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Extend the EET DML oracle to INSERT support by tlmorgan24 · Pull Request #1358 · sqlancer/sqlancer · GitHub

Extend the EET DML oracle to INSERT support - #1358

Merged
mrigger merged 3 commits into
mainfrom
feature/eet-insert
Aug 16, 2026
Merged

Extend the EET DML oracle to INSERT support#1358
mrigger merged 3 commits into
mainfrom
feature/eet-insert

Conversation

tlmorgan24 commented Aug 13, 2026
edited
Loading

Copy link
Copy Markdown
Collaborator

The EET DML oracle (EETDMLOracle) previously transformed DELETE and UPDATE statements. This PR adds INSERT to the same oracle.

The INSERT is generated in the INSERT ... SELECT form rather than INSERT ... VALUES. This is because, when a value expression is transformed, the transformer introduces equivalent sub-expressions that reference the table's columns (for example, the random predicate inside a CASE WHEN). Column references are legal in a SELECT but not in a VALUES clause, so a VALUES form would produce invalid SQL without additional workarounds. Note, this does NOT mean that the testing is limited to only insert column references. It can still insert new constants too. For example, INSERT INTO t (c1) SELECT (123) FROM t WHERE p would insert n rows with the constant 123, where n is the number of rows in t which satisfy p. So, the INSERT ... SELECT form is expected to stress the DBMS at least as much as the INSERT ... VALUES form would.

Because INSERT ... SELECT inserts one new row per source row, each new row needs an identifier so the two runs' states can be lined up. Although the existing rows are originally stamped with UUID(), this cannot be used for the inserted rows, because it would be non-deterministic across the two runs. The implementation chosen here for MySQL simply removes the four dashes from the existing row's rowid, using REPLACE(rowid, '-', ''). This is deterministic (both runs assign the same identifiers), unique per source row, and distinct from every existing identifier (a 32-character string never equals the 36-character source string). It also fits the existing identifier column without widening it.

tlmorgan24 requested a review from mrigger August 13, 2026 05:59

mrigger commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

The INSERT is generated in the INSERT ... SELECT form rather than INSERT ... VALUES.

Just a quick check: assuming that this is a workaround, could we just set the column list in the generator temporarily to be empty? Not sure if I understood the problem correctly.

mrigger left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

LGTM! Just waiting for a response to the other comment I just posted before merging.

@Override
public List<MySQLExpression> generateInsertValues() {
// One value per content column, in schema order (aligned with the INSERT column list). As with the normal
// INSERT workload, each value is an arbitrary expression (not type-matched to the column); any resulting

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Ah, I wasn't aware or forgot that the INSERT generator is untyped. Probably, it should be typed, as it would make it much more likely to generate meaningful databases. But, I guess that's for another PR.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Choose a reason Spam Abuse Off Topic Outdated Duplicate Resolved Low Quality

Yes, FYI this isn't MySQL-specific, it is a similar story for most other weakly typed DBMSs

tlmorgan24 commented Aug 14, 2026
edited
Loading

Copy link
Copy Markdown
Collaborator Author

The INSERT is generated in the INSERT ... SELECT form rather than INSERT ... VALUES.

Just a quick check: assuming that this is a workaround, could we just set the column list in the generator temporarily to be empty? Not sure if I understood the problem correctly.

Yes, it is possible to implement INSERT ... VALUES. The decision was mainly which of the two to implement first, and the other could be a later PR. I ended up thinking that INSERT ... SELECT was a simpler initial implementation, as it slots into the UPDATE and DELETE path more naturally, using the same DMLStatementGenerator signature. It also offers more transformation points (values and predicate) than INSERT ... VALUES (values only), potentially stressing the DBMS more. That said, INSERT ... VALUES may use a different execution path than INSERT ... SELECT, so adding it would still increase coverage some more.

mrigger enabled auto-merge August 16, 2026 16:22
mrigger disabled auto-merge August 16, 2026 16:22
mrigger merged commit a00e636 into main Aug 16, 2026
69 of 75 checks passed
mrigger deleted the feature/eet-insert branch August 16, 2026 16:23
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
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


Back | FazBrowse Home | New Git URL