Repository navigation
Conversation
|
|
SummaryThe run covers normal database operations such as creating tables, inserting and querying typed data, joins, prepared statements, constraints, and transaction commits, along with boundary values and invalid-input handling. It also exercises failure recovery and multi-step transaction behavior, where data and schema integrity are expected to be preserved after errors. Not safe to merge yet — the PR introduces high-severity transaction integrity failures that can leave unintended schema and data changes after errors, including executing work that should have been rolled back. These are merge-blocking correctness and data-safety risks; the other successful coverage does not offset them. Tests run by ItoTip Reply with @itoqa to send us feedback on this test run. |
| github.com/dolthub/eventsapi_schema v0.0.0-20260715220557-d9b4a1c6b4d4 | ||
| github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 | ||
| github.com/dolthub/go-mysql-server v0.20.1-0.20260921092145-13a83f1e6133 | ||
| github.com/dolthub/go-mysql-server v0.20.1-0.20260923233949-d8613573a711 |
There was a problem hiding this comment.
Rollback leaves a partial table behind
What failed: Rolling back the failed operation did not remove the table created in the same transaction, even though the later valid row was committed correctly.
Impact · Steps · Stub / mock · Analysis · Why this is likely a bug
- Severity: High
- Impact: A failed transaction can leave a table behind even after rollback, creating a durable partial database change. Users may need to remove the leftover table manually and cannot rely on rollback to restore the prior schema.
- Steps to Reproduce:
- Connect to the local PostgreSQL endpoint and remove any old copies of the two test tables.
- Create the valid table, begin a transaction, and create a second table inside that transaction.
- Insert a text value into the second table's integer column so the server returns an integer conversion error.
- Issue ROLLBACK, insert (1, 42) into the valid table, and commit.
- From a separate connection, list both tables and read the valid row. The valid row exists, but the transaction-created table also remains visible.
- Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
- Code Analysis: The recorded SQL sequence creates bf_fail3_partial after BEGIN, fails while inserting the incompatible value, and then executes ROLLBACK. The independent information_schema query still returns bf_fail3_partial, proving that the failed transaction left a schema object visible to another connection. This is consistent with an engine transaction-boundary regression rather than a client display problem: server/connection_transaction.go:99-102 routes ROLLBACK through the engine transaction-control path, and server/connection_transaction.go:212-219 executes that control statement through DoltgresHandler.ComQuery. The PR changes the go-mysql-server module version at go.mod:12 from 20260921092145-13a83f1e6133 to 20260923233949-d8613573a711, so the shared engine implementation used by that path is the direct changed-code cause. The smallest practical fix is to revert or pin the new module version, or fix its transaction commit/rollback handling so DDL created after BEGIN is discarded on ROLLBACK; no broad protocol rewrite is needed.
- Why this is likely a bug: The failure is reproducible through the PostgreSQL wire endpoint and survives an independent-connection readback, so it is not limited to transaction status shown on the original session. Existing repository coverage explicitly treats a table created inside a transaction as absent after ROLLBACK, which establishes the product contract. Leaving that table visible creates a durable partial schema change after the user requested recovery, while ordinary transaction recovery and the later valid insert otherwise appear successful. The direct dependency change in go.mod is the only PR code change and supplies the engine behavior, making it the practical regression point.
Relevant code
server/connection_transaction.go:99-102
case *sqlparser.Rollback:
h.state.txState = idleTransactionState
h.clearTransactionLocalVars()
return false, nilserver/connection_transaction.go:212-219
func (h *ConnectionHandler) runEngineTransactionControl(statement string) error {
queries, err := h.convertQuery(statement)
if err != nil {
return err
}
return h.doltgresHandler.ComQuery(context.Background(), h.mysqlConn, queries[0].String, queries[0].AST, func(*sql.Context, *Result) error { return nil })
}go.mod:12
github.com/dolthub/go-mysql-server v0.20.1-0.20260923233949-d8613573a711
testing/go/smoke_test.go:43-54
Query: "BEGIN",
...
Query: "CREATE TABLE rolled_back AS SELECT 1 AS v",
...
Query: "ROLLBACK",
...
Query: "SELECT to_regclass('rolled_back')",
Expected: []sql.Row{{nil}}Evidence Package
Copy prompt for an agent
Ito QA identified the following failure during automated PR testing. Please investigate and propose a fix.
**High severity — Rollback leaves a partial table behind**
**What failed:** Rolling back the failed operation did not remove the table created in the same transaction, even though the later valid row was committed correctly.
- **Impact:** A failed transaction can leave a table behind even after rollback, creating a durable partial database change. Users may need to remove the leftover table manually and cannot rely on rollback to restore the prior schema.
- **Steps to reproduce:**
1. Connect to the local PostgreSQL endpoint and remove any old copies of the two test tables.
2. Create the valid table, begin a transaction, and create a second table inside that transaction.
3. Insert a text value into the second table's integer column so the server returns an integer conversion error.
4. Issue ROLLBACK, insert (1, 42) into the valid table, and commit.
5. From a separate connection, list both tables and read the valid row. The valid row exists, but the transaction-created table also remains visible.
- **Stub / mock content:** No stubs, mocks, or bypasses were applied for this test in the recorded run.
- **Code analysis:** The recorded SQL sequence creates bf_fail3_partial after BEGIN, fails while inserting the incompatible value, and then executes ROLLBACK. The independent information_schema query still returns bf_fail3_partial, proving that the failed transaction left a schema object visible to another connection. This is consistent with an engine transaction-boundary regression rather than a client display problem: server/connection_transaction.go:99-102 routes ROLLBACK through the engine transaction-control path, and server/connection_transaction.go:212-219 executes that control statement through DoltgresHandler.ComQuery. The PR changes the go-mysql-server module version at go.mod:12 from 20260921092145-13a83f1e6133 to 20260923233949-d8613573a711, so the shared engine implementation used by that path is the direct changed-code cause. The smallest practical fix is to revert or pin the new module version, or fix its transaction commit/rollback handling so DDL created after BEGIN is discarded on ROLLBACK; no broad protocol rewrite is needed.
- **Why this is likely a bug:** The failure is reproducible through the PostgreSQL wire endpoint and survives an independent-connection readback, so it is not limited to transaction status shown on the original session. Existing repository coverage explicitly treats a table created inside a transaction as absent after ROLLBACK, which establishes the product contract. Leaving that table visible creates a durable partial schema change after the user requested recovery, while ordinary transaction recovery and the later valid insert otherwise appear successful. The direct dependency change in go.mod is the only PR code change and supplies the engine behavior, making it the practical regression point.
**Relevant code:**
`server/connection_transaction.go:99-102`
~~~go
case *sqlparser.Rollback:
h.state.txState = idleTransactionState
h.clearTransactionLocalVars()
return false, nil
~~~
`server/connection_transaction.go:212-219`
~~~go
func (h *ConnectionHandler) runEngineTransactionControl(statement string) error {
queries, err := h.convertQuery(statement)
if err != nil {
return err
}
return h.doltgresHandler.ComQuery(context.Background(), h.mysqlConn, queries[0].String, queries[0].AST, func(*sql.Context, *Result) error { return nil })
}
~~~
`go.mod:12`
~~~text
github.com/dolthub/go-mysql-server v0.20.1-0.20260923233949-d8613573a711
~~~
`testing/go/smoke_test.go:43-54`
~~~go
Query: "BEGIN",
...
Query: "CREATE TABLE rolled_back AS SELECT 1 AS v",
...
Query: "ROLLBACK",
...
Query: "SELECT to_regclass('rolled_back')",
Expected: []sql.Row{{nil}}
~~~| github.com/dolthub/eventsapi_schema v0.0.0-20260715220557-d9b4a1c6b4d4 | ||
| github.com/dolthub/flatbuffers/v23 v23.3.3-dh.2 | ||
| github.com/dolthub/go-mysql-server v0.20.1-0.20260921092145-13a83f1e6133 | ||
| github.com/dolthub/go-mysql-server v0.20.1-0.20260923233949-d8613573a711 |
There was a problem hiding this comment.
Failed SQL batch keeps partial writes
What failed: The database reported the division-by-zero error, but it kept the first insert and ran the insert after the error. The failed batch should have rolled back all its writes, skipped later statements, and allowed the next insert to create the only row.
Impact · Steps · Stub / mock · Analysis · Why this is likely a bug
- Severity: High
- Impact: A failed multi-step database request can leave some writes saved and run later writes that should have been skipped. Users may be left with incorrect data and need manual cleanup or a corrective retry.
- Steps to Reproduce:
- Connect to the local database and create a table named mytable with BIGINT primary-key column i.
- Send one simple-query message containing: INSERT INTO mytable VALUES (1); SELECT 1/0; INSERT INTO mytable VALUES (2);.
- On a second connection, query SELECT count(*) FROM mytable;.
- On the original connection, run INSERT INTO mytable VALUES (3); and then SELECT i FROM mytable ORDER BY i;.
- Observe the division-by-zero error, count 2 on the second connection, and rows 1, 2, and 3 on the original connection.
- Stub / mock content: No stubs, mocks, or bypasses were applied for this test in the recorded run.
- Code Analysis: The production path in server/connection_simple.go treats a multi-statement Query message as one implicit transaction by setting implicitTransactionControl when more than one statement is present, calling startImplicitTransaction before each statement, and returning immediately when h.query returns an error. server/connection_errors.go then routes the simple-protocol error through endOfMessages and handleOperationError, which calls failActiveTransaction. server/connection_transaction.go shows that failActiveTransaction should call rollbackImplicitTransaction for implicitTransactionState, and rollbackImplicitTransaction should issue ROLLBACK before returning the session to idle. The recorded result contradicts that intended control flow: row 1 remains visible, row 2 was executed, and the next statement sees both rows. The PR changes the go-mysql-server dependency in go.mod from 0.20.1-0.20260921092145-13a83f1e6133 to 0.20.1-0.20260923233949-d8613573a711 (go.mod line 12); this dependency change is the only production change in the PR and is the practical cause to investigate for the engine transaction-control behavior. The smallest fix is to restore or correct the dependency transaction semantics so an error in a simple-query implicit transaction reliably invokes rollback and stops the remaining statements; add or run the existing regression test before retaining the dependency bump.
- Why this is likely a bug: The failure is reproducible through the database wire protocol with two independent connections and produces a concrete data-integrity violation: a failed batch leaves row 1 committed, executes row 2 despite the earlier error, and then exposes both rows to another connection. The repository's existing implicit_transaction_test.go independently defines this exact behavior as rollback of the whole Query message, suppression of statements after the error, and successful recovery for the following Query message. The local setup did not mock database behavior or intercept the SQL, and no test-only code changes were made. Because the PR's only application-affecting change is the go-mysql-server version bump, the changed dependency's transaction behavior is a direct regression surface; the targeted remediation is to fix or revert that dependency change, not to rewrite the connection handler.
Relevant code
server/connection_simple.go:58-76
// Multiple statements in one Query message run in an implicit transaction block.
implicitTransactionControl := len(execution.statements) > 1
...
if err = h.query(query); err != nil {
return true, err
}server/connection_errors.go:43-47
func (h *ConnectionHandler) endOfMessages(err error) {
if err != nil {
h.handleOperationError(err)
}server/connection_transaction.go:178-185
func (h *ConnectionHandler) failActiveTransaction() {
switch h.state.txState {
case implicitTransactionState:
h.rollbackImplicitTransaction()testing/go/implicit_transaction_test.go:90-112
Name: "error rolls back the entire implicit transaction"
...
ExpectedErr: "division by zero"
...
Expected: [][]string{{"0"}}
...
Expected: [][]string{{"3"}}go.mod:12
github.com/dolthub/go-mysql-server v0.20.1-0.20260923233949-d8613573a711Evidence Package
Copy prompt for an agent
Ito QA identified the following failure during automated PR testing. Please investigate and propose a fix.
**High severity — Failed SQL batch keeps partial writes**
**What failed:** The database reported the division-by-zero error, but it kept the first insert and ran the insert after the error. The failed batch should have rolled back all its writes, skipped later statements, and allowed the next insert to create the only row.
- **Impact:** A failed multi-step database request can leave some writes saved and run later writes that should have been skipped. Users may be left with incorrect data and need manual cleanup or a corrective retry.
- **Steps to reproduce:**
1. Connect to the local database and create a table named mytable with BIGINT primary-key column i.
2. Send one simple-query message containing: INSERT INTO mytable VALUES (1); SELECT 1/0; INSERT INTO mytable VALUES (2);.
3. On a second connection, query SELECT count(*) FROM mytable;.
4. On the original connection, run INSERT INTO mytable VALUES (3); and then SELECT i FROM mytable ORDER BY i;.
5. Observe the division-by-zero error, count 2 on the second connection, and rows 1, 2, and 3 on the original connection.
- **Stub / mock content:** No stubs, mocks, or bypasses were applied for this test in the recorded run.
- **Code analysis:** The production path in server/connection_simple.go treats a multi-statement Query message as one implicit transaction by setting implicitTransactionControl when more than one statement is present, calling startImplicitTransaction before each statement, and returning immediately when h.query returns an error. server/connection_errors.go then routes the simple-protocol error through endOfMessages and handleOperationError, which calls failActiveTransaction. server/connection_transaction.go shows that failActiveTransaction should call rollbackImplicitTransaction for implicitTransactionState, and rollbackImplicitTransaction should issue ROLLBACK before returning the session to idle. The recorded result contradicts that intended control flow: row 1 remains visible, row 2 was executed, and the next statement sees both rows. The PR changes the go-mysql-server dependency in go.mod from 0.20.1-0.20260921092145-13a83f1e6133 to 0.20.1-0.20260923233949-d8613573a711 (go.mod line 12); this dependency change is the only production change in the PR and is the practical cause to investigate for the engine transaction-control behavior. The smallest fix is to restore or correct the dependency transaction semantics so an error in a simple-query implicit transaction reliably invokes rollback and stops the remaining statements; add or run the existing regression test before retaining the dependency bump.
- **Why this is likely a bug:** The failure is reproducible through the database wire protocol with two independent connections and produces a concrete data-integrity violation: a failed batch leaves row 1 committed, executes row 2 despite the earlier error, and then exposes both rows to another connection. The repository's existing implicit_transaction_test.go independently defines this exact behavior as rollback of the whole Query message, suppression of statements after the error, and successful recovery for the following Query message. The local setup did not mock database behavior or intercept the SQL, and no test-only code changes were made. Because the PR's only application-affecting change is the go-mysql-server version bump, the changed dependency's transaction behavior is a direct regression surface; the targeted remediation is to fix or revert that dependency change, not to rewrite the connection handler.
**Relevant code:**
`server/connection_simple.go:58-76`
~~~go
// Multiple statements in one Query message run in an implicit transaction block.
implicitTransactionControl := len(execution.statements) > 1
...
if err = h.query(query); err != nil {
return true, err
}
~~~
`server/connection_errors.go:43-47`
~~~go
func (h *ConnectionHandler) endOfMessages(err error) {
if err != nil {
h.handleOperationError(err)
}
~~~
`server/connection_transaction.go:178-185`
~~~go
func (h *ConnectionHandler) failActiveTransaction() {
switch h.state.txState {
case implicitTransactionState:
h.rollbackImplicitTransaction()
~~~
`testing/go/implicit_transaction_test.go:90-112`
~~~go
Name: "error rolls back the entire implicit transaction"
...
ExpectedErr: "division by zero"
...
Expected: [][]string{{"0"}}
...
Expected: [][]string{{"3"}}
~~~
`go.mod:12`
~~~go
github.com/dolthub/go-mysql-server v0.20.1-0.20260923233949-d8613573a711
~~~|
@elianddb DOLT
|

No description provided.