1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/hanchuanchuan-goInception

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
stmtctx.go 7 КБ
Копировать Редактировать Исходные данные Просмотреть построчно История
hanchuanchuan Отправлено 6 лет назад 27f3c5a
// Copyright 2017 PingCAP, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
package stmtctx
import (
"math"
"sync"
"time"
"github.com/hanchuanchuan/goInception/mysql"
"github.com/hanchuanchuan/goInception/util/execdetails"
"github.com/hanchuanchuan/goInception/util/memory"
)
const (
// WarnLevelError represents level "Error" for 'SHOW WARNINGS' syntax.
WarnLevelError = "Error"
// WarnLevelWarning represents level "Warning" for 'SHOW WARNINGS' syntax.
WarnLevelWarning = "Warning"
// WarnLevelNote represents level "Note" for 'SHOW WARNINGS' syntax.
WarnLevelNote = "Note"
)
// SQLWarn relates a sql warning and it's level.
type SQLWarn struct {
Level string
Err error
}
// StatementContext contains variables for a statement.
// It should be reset before executing a statement.
type StatementContext struct {
// Set the following variables before execution
// IsDDLJobInQueue is used to mark whether the DDL job is put into the queue.
// If IsDDLJobInQueue is true, it means the DDL job is in the queue of storage, and it can be handled by the DDL worker.
IsDDLJobInQueue bool
InInsertStmt bool
InUpdateOrDeleteStmt bool
InSelectStmt bool
IgnoreTruncate bool
IgnoreZeroInDate bool
DupKeyAsWarning bool
BadNullAsWarning bool
DividedByZeroAsWarning bool
TruncateAsWarning bool
OverflowAsWarning bool
InShowWarning bool
UseCache bool
PadCharToFullLength bool
BatchCheck bool
InNullRejectCheck bool
// mu struct holds variables that change during execution.
mu struct {
sync.Mutex
affectedRows uint64
foundRows uint64
warnings []SQLWarn
histogramsNotLoad bool
execDetails execdetails.ExecDetails
}
// Copied from SessionVars.TimeZone.
TimeZone *time.Location
Priority mysql.PriorityEnum
NotFillCache bool
MemTracker *memory.Tracker
RuntimeStatsColl *execdetails.RuntimeStatsColl
TableIDs []int64
IndexIDs []int64
}
// AddAffectedRows adds affected rows.
func (sc *StatementContext) AddAffectedRows(rows uint64) {
sc.mu.Lock()
sc.mu.affectedRows += rows
sc.mu.Unlock()
}
// AffectedRows gets affected rows.
func (sc *StatementContext) AffectedRows() uint64 {
sc.mu.Lock()
rows := sc.mu.affectedRows
sc.mu.Unlock()
return rows
}
// FoundRows gets found rows.
func (sc *StatementContext) FoundRows() uint64 {
sc.mu.Lock()
rows := sc.mu.foundRows
sc.mu.Unlock()
return rows
}
// AddFoundRows adds found rows.
func (sc *StatementContext) AddFoundRows(rows uint64) {
sc.mu.Lock()
sc.mu.foundRows += rows
sc.mu.Unlock()
}
// GetWarnings gets warnings.
func (sc *StatementContext) GetWarnings() []SQLWarn {
sc.mu.Lock()
warns := make([]SQLWarn, len(sc.mu.warnings))
copy(warns, sc.mu.warnings)
sc.mu.Unlock()
return warns
}
// WarningCount gets warning count.
func (sc *StatementContext) WarningCount() uint16 {
if sc.InShowWarning {
return 0
}
sc.mu.Lock()
wc := uint16(len(sc.mu.warnings))
sc.mu.Unlock()
return wc
}
// NumWarnings gets warning count. It's different from `WarningCount` in that
// `WarningCount` return the warning count of the last executed command, so if
// the last command is a SHOW statement, `WarningCount` return 0. On the other
// hand, `NumWarnings` always return number of warnings(or errors if `errOnly`
// is set).
func (sc *StatementContext) NumWarnings(errOnly bool) uint16 {
var wc uint16
sc.mu.Lock()
defer sc.mu.Unlock()
if errOnly {
for _, warn := range sc.mu.warnings {
if warn.Level == WarnLevelError {
wc++
}
}
} else {
wc = uint16(len(sc.mu.warnings))
}
return wc
}
// SetWarnings sets warnings.
func (sc *StatementContext) SetWarnings(warns []SQLWarn) {
sc.mu.Lock()
sc.mu.warnings = warns
sc.mu.Unlock()
}
// AppendWarning appends a warning with level 'Warning'.
func (sc *StatementContext) AppendWarning(warn error) {
sc.mu.Lock()
if len(sc.mu.warnings) < math.MaxUint16 {
sc.mu.warnings = append(sc.mu.warnings, SQLWarn{WarnLevelWarning, warn})
}
sc.mu.Unlock()
}
// AppendNote appends a warning with level 'Note'.
func (sc *StatementContext) AppendNote(warn error) {
sc.mu.Lock()
if len(sc.mu.warnings) < math.MaxUint16 {
sc.mu.warnings = append(sc.mu.warnings, SQLWarn{WarnLevelNote, warn})
}
sc.mu.Unlock()
}
// AppendError appends a warning with level 'Error'.
func (sc *StatementContext) AppendError(warn error) {
sc.mu.Lock()
if len(sc.mu.warnings) < math.MaxUint16 {
sc.mu.warnings = append(sc.mu.warnings, SQLWarn{WarnLevelError, warn})
}
sc.mu.Unlock()
}
// SetHistogramsNotLoad sets histogramsNotLoad.
func (sc *StatementContext) SetHistogramsNotLoad() {
sc.mu.Lock()
sc.mu.histogramsNotLoad = true
sc.mu.Unlock()
}
// HistogramsNotLoad gets histogramsNotLoad.
func (sc *StatementContext) HistogramsNotLoad() bool {
sc.mu.Lock()
notLoad := sc.mu.histogramsNotLoad
sc.mu.Unlock()
return notLoad
}
// HandleTruncate ignores or returns the error based on the StatementContext state.
func (sc *StatementContext) HandleTruncate(err error) error {
// TODO: At present we have not checked whether the error can be ignored or treated as warning.
// We will do that later, and then append WarnDataTruncated instead of the error itself.
if err == nil {
return nil
}
if sc.IgnoreTruncate {
return nil
}
if sc.TruncateAsWarning {
sc.AppendWarning(err)
return nil
}
return err
}
// HandleOverflow treats ErrOverflow as warnings or returns the error based on the StmtCtx.OverflowAsWarning state.
func (sc *StatementContext) HandleOverflow(err error, warnErr error) error {
if err == nil {
return nil
}
if sc.OverflowAsWarning {
sc.AppendWarning(warnErr)
return nil
}
return err
}
// ResetForRetry resets the changed states during execution.
func (sc *StatementContext) ResetForRetry() {
sc.mu.Lock()
sc.mu.affectedRows = 0
sc.mu.foundRows = 0
sc.mu.warnings = nil
sc.mu.Unlock()
}
// MergeExecDetails merges a single region execution details into self, used to print
// the information in slow query log.
func (sc *StatementContext) MergeExecDetails(details *execdetails.ExecDetails) {
sc.mu.Lock()
sc.mu.execDetails.ProcessTime += details.ProcessTime
sc.mu.execDetails.WaitTime += details.WaitTime
sc.mu.execDetails.BackoffTime += details.BackoffTime
sc.mu.execDetails.RequestCount++
sc.mu.execDetails.TotalKeys += details.TotalKeys
sc.mu.execDetails.ProcessedKeys += details.ProcessedKeys
sc.mu.Unlock()
}
// GetExecDetails gets the execution details for the statement.
func (sc *StatementContext) GetExecDetails() execdetails.ExecDetails {
var details execdetails.ExecDetails
sc.mu.Lock()
details = sc.mu.execDetails
sc.mu.Unlock()
return details
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://gitlife.ru/oschina-mirror/hanchuanchuan-goInception.git
git@gitlife.ru:oschina-mirror/hanchuanchuan-goInception.git
oschina-mirror
hanchuanchuan-goInception
hanchuanchuan-goInception
v1.2.3