diff --git a/distsql/request_builder.go b/distsql/request_builder.go index 328977a98247b..83161d0f25dd7 100644 --- a/distsql/request_builder.go +++ b/distsql/request_builder.go @@ -125,7 +125,13 @@ func (builder *RequestBuilder) SetKeepOrder(order bool) *RequestBuilder { } func (builder *RequestBuilder) getIsolationLevel(sv *variable.SessionVars) kv.IsoLevel { - isoLevel, _ := sv.GetSystemVar(variable.TxnIsolation) + var isoLevel string + if sv.TxnIsolationLevelOneShot.State == 2 { + isoLevel = sv.TxnIsolationLevelOneShot.Value + } + if isoLevel == "" { + isoLevel, _ = sv.GetSystemVar(variable.TxnIsolation) + } if isoLevel == ast.ReadCommitted { return kv.RC } diff --git a/executor/executor.go b/executor/executor.go index cbc56398b0fc2..294d07df1afd2 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -66,29 +66,31 @@ var ( // Error instances. var ( - ErrUnknownPlan = terror.ClassExecutor.New(codeUnknownPlan, "Unknown plan") - ErrPrepareMulti = terror.ClassExecutor.New(codePrepareMulti, "Can not prepare multiple statements") - ErrPrepareDDL = terror.ClassExecutor.New(codePrepareDDL, "Can not prepare DDL statements") - ErrPasswordNoMatch = terror.ClassExecutor.New(CodePasswordNoMatch, "Can't find any matching row in the user table") - ErrResultIsEmpty = terror.ClassExecutor.New(codeResultIsEmpty, "result is empty") - ErrBuildExecutor = terror.ClassExecutor.New(codeErrBuildExec, "Failed to build executor") - ErrBatchInsertFail = terror.ClassExecutor.New(codeBatchInsertFail, "Batch insert failed, please clean the table and try again.") - ErrWrongValueCountOnRow = terror.ClassExecutor.New(codeWrongValueCountOnRow, "Column count doesn't match value count at row %d") - ErrPasswordFormat = terror.ClassExecutor.New(codePasswordFormat, "The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function.") + ErrUnknownPlan = terror.ClassExecutor.New(codeUnknownPlan, "Unknown plan") + ErrPrepareMulti = terror.ClassExecutor.New(codePrepareMulti, "Can not prepare multiple statements") + ErrPrepareDDL = terror.ClassExecutor.New(codePrepareDDL, "Can not prepare DDL statements") + ErrPasswordNoMatch = terror.ClassExecutor.New(CodePasswordNoMatch, "Can't find any matching row in the user table") + ErrResultIsEmpty = terror.ClassExecutor.New(codeResultIsEmpty, "result is empty") + ErrBuildExecutor = terror.ClassExecutor.New(codeErrBuildExec, "Failed to build executor") + ErrBatchInsertFail = terror.ClassExecutor.New(codeBatchInsertFail, "Batch insert failed, please clean the table and try again.") + ErrWrongValueCountOnRow = terror.ClassExecutor.New(codeWrongValueCountOnRow, "Column count doesn't match value count at row %d") + ErrPasswordFormat = terror.ClassExecutor.New(codePasswordFormat, "The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function.") + ErrCantChangeTxCharacteristics = terror.ClassExecutor.New(codeErrCantChangeTxCharacteristics, "Transaction characteristics can't be changed while a transaction is in progress") ) // Error codes. const ( - codeUnknownPlan terror.ErrCode = 1 - codePrepareMulti terror.ErrCode = 2 - codePrepareDDL terror.ErrCode = 7 - codeResultIsEmpty terror.ErrCode = 8 - codeErrBuildExec terror.ErrCode = 9 - codeBatchInsertFail terror.ErrCode = 10 - CodePasswordNoMatch terror.ErrCode = 1133 // MySQL error code - CodeCannotUser terror.ErrCode = 1396 // MySQL error code - codeWrongValueCountOnRow terror.ErrCode = 1136 // MySQL error code - codePasswordFormat terror.ErrCode = 1827 // MySQL error code + codeUnknownPlan terror.ErrCode = 1 + codePrepareMulti terror.ErrCode = 2 + codePrepareDDL terror.ErrCode = 7 + codeResultIsEmpty terror.ErrCode = 8 + codeErrBuildExec terror.ErrCode = 9 + codeBatchInsertFail terror.ErrCode = 10 + CodePasswordNoMatch terror.ErrCode = 1133 // MySQL error code + CodeCannotUser terror.ErrCode = 1396 // MySQL error code + codeWrongValueCountOnRow terror.ErrCode = 1136 // MySQL error code + codePasswordFormat terror.ErrCode = 1827 // MySQL error code + codeErrCantChangeTxCharacteristics terror.ErrCode = 1568 ) // Row represents a result set row, it may be returned from a table, a join, or a projection. @@ -604,10 +606,11 @@ func init() { } } tableMySQLErrCodes := map[terror.ErrCode]uint16{ - CodeCannotUser: mysql.ErrCannotUser, - CodePasswordNoMatch: mysql.ErrPasswordNoMatch, - codeWrongValueCountOnRow: mysql.ErrWrongValueCountOnRow, - codePasswordFormat: mysql.ErrPasswordFormat, + CodeCannotUser: mysql.ErrCannotUser, + CodePasswordNoMatch: mysql.ErrPasswordNoMatch, + codeWrongValueCountOnRow: mysql.ErrWrongValueCountOnRow, + codePasswordFormat: mysql.ErrPasswordFormat, + codeErrCantChangeTxCharacteristics: mysql.ErrCantChangeTxCharacteristics, } terror.ErrClassToMySQLCodes[terror.ClassExecutor] = tableMySQLErrCodes } diff --git a/executor/set.go b/executor/set.go index 43cfa8c74df53..3575de68d365b 100644 --- a/executor/set.go +++ b/executor/set.go @@ -150,6 +150,9 @@ func (e *SetExecutor) setSysVariable(name string, v *expression.VarAssignment) e return errors.Trace(err) } oldSnapshotTS := sessionVars.SnapshotTS + if name == variable.TxnIsolationOneShot && sessionVars.InTxn() { + return errors.Trace(ErrCantChangeTxCharacteristics) + } err = variable.SetSessionSystemVar(sessionVars, name, value) if err != nil { return errors.Trace(err) diff --git a/parser/parser.y b/parser/parser.y index a67b6926ebdde..abfaa0831043b 100644 --- a/parser/parser.y +++ b/parser/parser.y @@ -4560,7 +4560,14 @@ SetStmt: } | "SET" "TRANSACTION" TransactionChars { - $$ = &ast.SetStmt{Variables: $3.([]*ast.VariableAssignment)} + assigns := $3.([]*ast.VariableAssignment) + for i:=0; i