*: merge master and fix conflict.

This commit is contained in:
siddontang
2015-11-12 10:21:50 +08:00
25 changed files with 834 additions and 75 deletions

2
.gitignore vendored
View File

@ -4,3 +4,5 @@
/interpreter/test
/tidb-server/tidb-server
coverage.out
.idea/
*.iml

View File

@ -162,6 +162,7 @@ const (
ShowWarnings
ShowCharset
ShowVariables
ShowStatus
ShowCollation
ShowCreateTable
ShowGrants

View File

@ -33,7 +33,6 @@ import (
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/parser/coldef"
"github.com/pingcap/tidb/privilege"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/charset"
@ -561,15 +560,6 @@ func (d *ddl) DropTable(ctx context.Context, ti table.Ident) (err error) {
if err != nil {
return errors.Trace(ErrNotExists)
}
// Check Privilege
privChecker := privilege.GetPrivilegeChecker(ctx)
hasPriv, err := privChecker.Check(ctx, schema, tb.Meta(), mysql.DropPriv)
if err != nil {
return errors.Trace(err)
}
if !hasPriv {
return errors.Errorf("You do not have the privilege to drop table %s.%s.", ti.Schema, ti.Name)
}
job := &model.Job{
SchemaID: schema.ID,

View File

@ -62,7 +62,7 @@ func (v *Variable) String() string {
func (v *Variable) Eval(ctx context.Context, args map[interface{}]interface{}) (interface{}, error) {
name := strings.ToLower(v.Name)
sessionVars := variable.GetSessionVars(ctx)
globalVars := variable.GetGlobalSysVarAccessor(ctx)
globalVars := variable.GetGlobalVarAccessor(ctx)
if !v.IsSystem {
// user vars
if value, ok := sessionVars.Users[name]; ok {

View File

@ -30,7 +30,7 @@ func (s *testVariableSuite) SetUpSuite(c *C) {
nc := mock.NewContext()
s.ctx = nc
variable.BindSessionVars(s.ctx)
variable.BindGlobalSysVarAccessor(s.ctx, nc)
variable.BindGlobalVarAccessor(s.ctx, nc)
}
func (s *testVariableSuite) TestVariable(c *C) {

View File

@ -868,6 +868,8 @@ func convertShow(converter *expressionConverter, v *ast.ShowStmt) (*stmts.ShowSt
oldShow.Target = stmt.ShowEngines
case ast.ShowVariables:
oldShow.Target = stmt.ShowVariables
case ast.ShowStatus:
oldShow.Target = stmt.ShowStatus
case ast.ShowWarnings:
oldShow.Target = stmt.ShowWarnings
case ast.ShowNone:

View File

@ -228,6 +228,7 @@ import (
signed "SIGNED"
some "SOME"
start "START"
status "STATUS"
stringType "string"
subDate "SUBDATE"
substring "SUBSTRING"
@ -482,10 +483,10 @@ import (
SelectStmtOpts "Select statement options"
SelectStmtGroup "SELECT statement optional GROUP BY clause"
SetStmt "Set variable statement"
ShowStmt "Show engines/databases/tables/columns/warnings statement"
ShowStmt "Show engines/databases/tables/columns/warnings/status statement"
ShowDatabaseNameOpt "Show tables/columns statement database name option"
ShowTableAliasOpt "Show table alias option"
ShowLikeOrWhereOpt "Show like or where condition option"
ShowLikeOrWhereOpt "Show like or where clause option"
SignedLiteral "Literal or NumLiteral with sign"
Statement "statement"
StatementList "statement list"
@ -1647,7 +1648,7 @@ UnReservedKeyword:
"AUTO_INCREMENT" | "AFTER" | "AVG" | "BEGIN" | "BIT" | "BOOL" | "BOOLEAN" | "CHARSET" | "COLUMNS" | "COMMIT"
| "DATE" | "DATETIME" | "DEALLOCATE" | "DO" | "END" | "ENGINE" | "ENGINES" | "EXECUTE" | "FIRST" | "FULL"
| "LOCAL" | "NAMES" | "OFFSET" | "PASSWORD" %prec lowerThanEq | "PREPARE" | "QUICK" | "ROLLBACK" | "SESSION" | "SIGNED"
| "START" | "GLOBAL" | "TABLES"| "TEXT" | "TIME" | "TIMESTAMP" | "TRANSACTION" | "TRUNCATE" | "UNKNOWN"
| "START" | "STATUS" | "GLOBAL" | "TABLES"| "TEXT" | "TIME" | "TIMESTAMP" | "TRANSACTION" | "TRUNCATE" | "UNKNOWN"
| "VALUE" | "WARNINGS" | "YEAR" | "MODE" | "WEEK" | "ANY" | "SOME" | "USER" | "IDENTIFIED" | "COLLATION"
| "COMMENT" | "AVG_ROW_LENGTH" | "CONNECTION" | "CHECKSUM" | "COMPRESSION" | "KEY_BLOCK_SIZE" | "MAX_ROWS" | "MIN_ROWS"
| "NATIONAL" | "ROW" | "QUARTER" | "ESCAPE" | "GRANTS"
@ -3316,6 +3317,19 @@ ShowStmt:
}
$$ = stmt
}
| "SHOW" GlobalScope "STATUS" ShowLikeOrWhereOpt
{
stmt := &ast.ShowStmt{
Tp: ast.ShowStatus,
GlobalScope: $2.(bool),
}
if x, ok := $4.(*ast.PatternLikeExpr); ok {
stmt.Pattern = x
} else if $4 != nil {
stmt.Where = $4.(ast.ExprNode)
}
$$ = stmt
}
| "SHOW" "COLLATION" ShowLikeOrWhereOpt
{
stmt := &ast.ShowStmt{

View File

@ -240,6 +240,11 @@ func (s *testParserSuite) TestDMLStmt(c *C) {
{"SHOW VARIABLES", true},
{"SHOW GLOBAL VARIABLES", true},
{"SHOW GLOBAL VARIABLES WHERE Variable_name = 'autocommit'", true},
{"SHOW STATUS", true},
{"SHOW GLOBAL STATUS", true},
{"SHOW SESSION STATUS", true},
{"SHOW STATUS LIKE 'Up%'", true},
{"SHOW STATUS WHERE Variable_name LIKE 'Up%'", true},
{`SHOW FULL TABLES FROM icar_qa LIKE play_evolutions`, true},
{`SHOW FULL TABLES WHERE Table_Type != 'VIEW'`, true},
{`SHOW GRANTS`, true},

View File

@ -430,6 +430,7 @@ share {s}{h}{a}{r}{e}
show {s}{h}{o}{w}
some {s}{o}{m}{e}
start {s}{t}{a}{r}{t}
status {s}{t}{a}{t}{u}{s}
subdate {s}{u}{b}{d}{a}{t}{e}
substring {s}{u}{b}{s}{t}{r}{i}{n}{g}
substring_index {s}{u}{b}{s}{t}{r}{i}{n}{g}_{i}{n}{d}{e}{x}
@ -841,6 +842,8 @@ year_month {y}{e}{a}{r}_{m}{o}{n}{t}{h}
return some
{start} lval.item = string(l.val)
return start
{status} lval.item = string(l.val)
return status
{global} lval.item = string(l.val)
return global
{rand} lval.item = string(l.val)

View File

@ -148,6 +148,7 @@ func (r *TableDefaultPlan) filterBinOp(ctx context.Context, x *expression.Binary
return &indexPlan{
src: t,
col: c,
unique: ix.Unique,
idxName: ix.Name.O,
idx: ix.X,
spans: toSpans(x.Op, rval, seekVal),
@ -179,6 +180,7 @@ func (r *TableDefaultPlan) filterIdent(ctx context.Context, x *expression.Ident,
return &indexPlan{
src: t,
col: v,
unique: ix.Unique,
idxName: ix.Name.L,
idx: ix.X,
spans: spans,
@ -215,6 +217,7 @@ func (r *TableDefaultPlan) filterIsNull(ctx context.Context, x *expression.IsNul
return &indexPlan{
src: t,
col: col,
unique: ix.Unique,
idxName: ix.Name.L,
idx: ix.X,
spans: spans,

View File

@ -25,6 +25,7 @@ import (
"github.com/pingcap/tidb/parser/opcode"
"github.com/pingcap/tidb/plan"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/format"
"github.com/pingcap/tidb/util/types"
)
@ -124,6 +125,7 @@ func (span *indexSpan) cutOffHigh(val interface{}, exclude bool) *indexSpan {
type indexPlan struct {
src table.Table
col *column.Col
unique bool
idxName string
idx kv.Index
spans []*indexSpan // multiple spans are ordered by their values and without overlapping.
@ -243,6 +245,7 @@ func (r *indexPlan) Filter(ctx context.Context, expr expression.Expression) (pla
return &indexPlan{
src: r.src,
col: r.col,
unique: r.unique,
idxName: r.idxName,
idx: r.idx,
spans: spans,
@ -325,19 +328,31 @@ func toSpans(op opcode.Op, val, seekVal interface{}) []*indexSpan {
}
// Next implements plan.Plan Next interface.
func (r *indexPlan) Next(ctx context.Context) (row *plan.Row, err error) {
func (r *indexPlan) Next(ctx context.Context) (*plan.Row, error) {
for {
if r.cursor == len(r.spans) {
return
return nil, nil
}
span := r.spans[r.cursor]
if r.isPointLookup(span) {
// Do point lookup on index will prevent prefetch cost.
row, err := r.pointLookup(ctx, span.lowVal)
if err != nil {
return nil, errors.Trace(err)
}
r.cursor++
if row != nil {
return row, nil
}
continue
}
if r.iter == nil {
seekVal := span.seekVal
if span.lowVal == minNotNullVal {
seekVal = []byte{}
}
var txn kv.Transaction
txn, err = ctx.GetTxn(false)
txn, err := ctx.GetTxn(false)
if err != nil {
return nil, errors.Trace(err)
}
@ -346,9 +361,7 @@ func (r *indexPlan) Next(ctx context.Context) (row *plan.Row, err error) {
return nil, types.EOFAsNil(err)
}
}
var idxKey []interface{}
var h int64
idxKey, h, err = r.iter.Next()
idxKey, h, err := r.iter.Next()
if err != nil {
return nil, types.EOFAsNil(err)
}
@ -370,20 +383,58 @@ func (r *indexPlan) Next(ctx context.Context) (row *plan.Row, err error) {
r.skipLowCmp = false
continue
}
row = &plan.Row{}
row.Data, err = r.src.Row(ctx, h)
var row *plan.Row
row, err = r.lookupRow(ctx, h)
if err != nil {
return nil, errors.Trace(err)
}
rowKey := &plan.RowKeyEntry{
Tbl: r.src,
Key: string(r.src.RecordKey(h, nil)),
}
row.RowKeys = append(row.RowKeys, rowKey)
return
return row, nil
}
}
func (r *indexPlan) isPointLookup(span *indexSpan) bool {
return r.unique && span.lowVal != nil && span.lowVal == span.highVal && !span.lowExclude && !span.highExclude
}
func (r *indexPlan) lookupRow(ctx context.Context, h int64) (*plan.Row, error) {
row := &plan.Row{}
var err error
row.Data, err = r.src.Row(ctx, h)
if err != nil {
return nil, errors.Trace(err)
}
rowKey := &plan.RowKeyEntry{
Tbl: r.src,
Key: string(r.src.RecordKey(h, nil)),
}
row.RowKeys = append(row.RowKeys, rowKey)
return row, nil
}
// pointLookup do not seek index but call Exists method to get a handle, which is cheaper.
func (r *indexPlan) pointLookup(ctx context.Context, val interface{}) (*plan.Row, error) {
txn, err := ctx.GetTxn(false)
if err != nil {
return nil, errors.Trace(err)
}
var exist bool
var h int64
// We expect a kv.ErrKeyExists Error because we pass -1 as the handle which is not equal to the existed handle.
exist, h, err = r.idx.Exist(txn, []interface{}{val}, -1)
if !exist {
return nil, errors.Trace(err)
}
if terror.ErrorNotEqual(kv.ErrKeyExists, err) {
return nil, errors.Trace(err)
}
var row *plan.Row
row, err = r.lookupRow(ctx, h)
if err != nil {
return nil, errors.Trace(err)
}
return row, nil
}
// Close implements plan.Plan Close interface.
func (r *indexPlan) Close() error {
if r.iter != nil {

View File

@ -32,6 +32,7 @@ import (
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/stmt"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/charset"
"github.com/pingcap/tidb/util/format"
)
@ -103,6 +104,8 @@ func (s *ShowPlan) GetFields() []*field.ResultField {
types = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong}
case stmt.ShowVariables:
names = []string{"Variable_name", "Value"}
case stmt.ShowStatus:
names = []string{"Variable_name", "Value"}
case stmt.ShowCollation:
names = []string{"Collation", "Charset", "Id", "Default", "Compiled", "Sortlen"}
types = []byte{mysql.TypeVarchar, mysql.TypeVarchar, mysql.TypeLonglong,
@ -164,6 +167,8 @@ func (s *ShowPlan) fetchAll(ctx context.Context) error {
return s.fetchShowCharset(ctx)
case stmt.ShowVariables:
return s.fetchShowVariables(ctx)
case stmt.ShowStatus:
return s.fetchShowStatus(ctx)
case stmt.ShowCollation:
return s.fetchShowCollation(ctx)
case stmt.ShowCreateTable:
@ -353,7 +358,7 @@ func (s *ShowPlan) fetchShowTables(ctx context.Context) error {
func (s *ShowPlan) fetchShowVariables(ctx context.Context) error {
sessionVars := variable.GetSessionVars(ctx)
globalVars := variable.GetGlobalSysVarAccessor(ctx)
globalVars := variable.GetGlobalVarAccessor(ctx)
m := map[interface{}]interface{}{}
for _, v := range variable.SysVars {
@ -402,6 +407,86 @@ func (s *ShowPlan) fetchShowVariables(ctx context.Context) error {
return nil
}
func getSessionStatusVar(ctx context.Context, sessionVars *variable.SessionVars,
globalVars variable.GlobalVarAccessor, name string) (string, error) {
sv, ok := sessionVars.StatusVars[name]
if ok {
return sv, nil
}
value, err := globalVars.GetGlobalStatusVar(ctx, name)
if err != nil && terror.UnknownStatusVar.Equal(err) {
return "", errors.Trace(err)
}
return value, nil
}
func getGlobalStatusVar(ctx context.Context, sessionVars *variable.SessionVars,
globalVars variable.GlobalVarAccessor, name string) (string, error) {
value, err := globalVars.GetGlobalStatusVar(ctx, name)
if err == nil {
return value, nil
}
if terror.UnknownStatusVar.Equal(err) {
return "", errors.Trace(err)
}
sv, _ := sessionVars.StatusVars[name]
return sv, nil
}
func (s *ShowPlan) fetchShowStatus(ctx context.Context) error {
sessionVars := variable.GetSessionVars(ctx)
globalVars := variable.GetGlobalVarAccessor(ctx)
m := map[interface{}]interface{}{}
for _, v := range variable.StatusVars {
if s.Pattern != nil {
s.Pattern.Expr = expression.Value{Val: v.Name}
} else if s.Where != nil {
m[expression.ExprEvalIdentFunc] = func(name string) (interface{}, error) {
if strings.EqualFold(name, "Variable_name") {
return v.Name, nil
}
return nil, errors.Errorf("unknown field %s", name)
}
}
match, err := s.evalCondition(ctx, m)
if err != nil {
return errors.Trace(err)
}
if !match {
continue
}
var value string
if !s.GlobalScope {
value, err = getSessionStatusVar(ctx, sessionVars, globalVars, v.Name)
if err != nil {
return errors.Trace(err)
}
} else if v.Scope != variable.ScopeSession {
value, err = getGlobalStatusVar(ctx, sessionVars, globalVars, v.Name)
if err != nil {
return errors.Trace(err)
}
} else {
continue
}
row := &plan.Row{Data: []interface{}{v.Name, value}}
s.rows = append(s.rows, row)
}
return nil
}
func (s *ShowPlan) fetchShowCharset(ctx context.Context) error {
// See: http://dev.mysql.com/doc/refman/5.7/en/show-character-set.html
descs := charset.GetAllCharsets()

View File

@ -56,7 +56,7 @@ func (p *testShowSuit) SetUpSuite(c *C) {
nc := mock.NewContext()
p.ctx = nc
variable.BindSessionVars(p.ctx)
variable.BindGlobalSysVarAccessor(p.ctx, nc)
variable.BindGlobalVarAccessor(p.ctx, nc)
p.dbName = "testshowplan"
p.store = newStore(c, p.dbName)
@ -106,7 +106,7 @@ func (p *testShowSuit) TestSimple(c *C) {
c.Assert(fls, HasLen, 2)
}
func (p *testShowSuit) TestShowVariables(c *C) {
func (p *testShowSuit) TestShowSysVariables(c *C) {
pln := &plans.ShowPlan{
Target: stmt.ShowVariables,
GlobalScope: true,
@ -182,6 +182,94 @@ func (p *testShowSuit) TestShowVariables(c *C) {
c.Assert(v, Equals, "on")
}
func (p *testShowSuit) TestShowStatusVariables(c *C) {
pln := &plans.ShowPlan{
Target: stmt.ShowStatus,
GlobalScope: true,
Pattern: &expression.PatternLike{
Pattern: &expression.Value{
Val: "tc_log_page_size",
},
},
}
fls := pln.GetFields()
c.Assert(fls, HasLen, 2)
c.Assert(fls[0].Name, Equals, "Variable_name")
c.Assert(fls[1].Name, Equals, "Value")
c.Assert(fls[0].Col.Tp, Equals, mysql.TypeVarchar)
c.Assert(fls[1].Col.Tp, Equals, mysql.TypeVarchar)
sessionVars := variable.GetSessionVars(p.ctx)
ret := map[string]string{}
rset := rsets.Recordset{
Ctx: p.ctx,
Plan: pln,
}
rset.Do(func(data []interface{}) (bool, error) {
ret[data[0].(string)] = data[1].(string)
return true, nil
})
c.Assert(ret, HasLen, 1)
v, ok := ret["tc_log_page_size"]
c.Assert(ok, IsTrue)
c.Assert(v, Equals, "0")
pln.Close()
sessionVars.StatusVars["tc_log_page_size"] = "1024"
pln.GlobalScope = false
rset.Do(func(data []interface{}) (bool, error) {
ret[data[0].(string)] = data[1].(string)
return true, nil
})
c.Assert(ret, HasLen, 1)
v, ok = ret["tc_log_page_size"]
c.Assert(ok, IsTrue)
c.Assert(v, Equals, "1024")
pln.Close()
pln.Pattern = &expression.PatternLike{
Pattern: &expression.Value{
Val: "compression",
},
}
sessionVars.StatusVars["compression"] = "on"
pln.GlobalScope = true
ret = map[string]string{}
rset.Do(func(data []interface{}) (bool, error) {
ret[data[0].(string)] = data[1].(string)
return true, nil
})
c.Assert(ret, HasLen, 0)
pln.GlobalScope = false
rset.Do(func(data []interface{}) (bool, error) {
ret[data[0].(string)] = data[1].(string)
return true, nil
})
c.Assert(ret, HasLen, 1)
v, ok = ret["compression"]
c.Assert(ok, IsTrue)
c.Assert(v, Equals, "on")
pln.Close()
pln.Pattern = nil
pln.Where = &expression.BinaryOperation{
L: &expression.Ident{CIStr: model.NewCIStr("Variable_name")},
R: expression.Value{Val: "aborted_clients"},
Op: opcode.EQ,
}
ret = map[string]string{}
sessionVars.StatusVars["aborted_clients"] = "0"
rset.Do(func(data []interface{}) (bool, error) {
ret[data[0].(string)] = data[1].(string)
return true, nil
})
c.Assert(ret, HasLen, 1)
v, ok = ret["aborted_clients"]
c.Assert(ok, IsTrue)
c.Assert(v, Equals, "0")
}
func (p *testShowSuit) TestIssue540(c *C) {
// Show variables where variable_name="time_zone"
pln := &plans.ShowPlan{

View File

@ -265,9 +265,9 @@ func (s *session) ExecRestrictedSQL(ctx context.Context, sql string) (rset.Recor
return rs, errors.Trace(err)
}
// GetGlobalSysVar implements RestrictedSQLExecutor.GetGlobalSysVar interface.
func (s *session) GetGlobalSysVar(ctx context.Context, name string) (string, error) {
sql := fmt.Sprintf(`SELECT VARIABLE_VALUE FROM %s.%s WHERE VARIABLE_NAME="%s";`, mysql.SystemDB, mysql.GlobalVariablesTable, name)
// getExecRet executes restricted sql and the result is one column.
// It returns a string value.
func (s *session) getExecRet(ctx context.Context, sql string) (string, error) {
rs, err := s.ExecRestrictedSQL(ctx, sql)
if err != nil {
return "", errors.Trace(err)
@ -278,7 +278,7 @@ func (s *session) GetGlobalSysVar(ctx context.Context, name string) (string, err
return "", errors.Trace(err)
}
if row == nil {
return "", fmt.Errorf("Unknown sys var: %s", name)
return "", terror.ExecResultIsEmpty
}
value, err := types.ToString(row.Data[0])
if err != nil {
@ -287,7 +287,44 @@ func (s *session) GetGlobalSysVar(ctx context.Context, name string) (string, err
return value, nil
}
// SetGlobalSysVar implements RestrictedSQLExecutor.SetGlobalSysVar interface.
// GetGlobalStatusVar implements GlobalVarAccessor.GetGlobalStatusVar interface.
func (s *session) GetGlobalStatusVar(ctx context.Context, name string) (string, error) {
// TODO: get global status variables from store.
v := variable.GetStatusVar(name)
if v == nil {
return "", terror.UnknownStatusVar.Gen("unknown status variable:%s", name)
}
return v.Value, nil
}
// SetGlobalStatusVar implements GlobalVarAccessor.SetGlobalStatusVar interface.
func (s *session) SetGlobalStatusVar(ctx context.Context, name string, value string) error {
// TODO: set global status variables from store.
v := variable.GetStatusVar(name)
if v == nil {
return terror.UnknownStatusVar.Gen("unknown status variable:%s", name)
}
v.Value = value
return nil
}
// GetGlobalSysVar implements GlobalVarAccessor.GetGlobalSysVar interface.
func (s *session) GetGlobalSysVar(ctx context.Context, name string) (string, error) {
sql := fmt.Sprintf(`SELECT VARIABLE_VALUE FROM %s.%s WHERE VARIABLE_NAME="%s";`, mysql.SystemDB, mysql.GlobalVariablesTable, name)
sysVar, err := s.getExecRet(ctx, sql)
if err != nil {
if terror.ExecResultIsEmpty.Equal(err) {
return "", terror.ExecResultIsEmpty.Gen("unknown sys variable:%s", name)
}
return "", errors.Trace(err)
}
return sysVar, nil
}
// SetGlobalSysVar implements GlobalVarAccessor.SetGlobalSysVar interface.
func (s *session) SetGlobalSysVar(ctx context.Context, name string, value string) error {
sql := fmt.Sprintf(`UPDATE %s.%s SET VARIABLE_VALUE="%s" WHERE VARIABLE_NAME="%s";`, mysql.SystemDB, mysql.GlobalVariablesTable, value, strings.ToLower(name))
_, err := s.ExecRestrictedSQL(ctx, sql)
@ -545,8 +582,8 @@ func CreateSession(store kv.Storage) (Session, error) {
variable.BindSessionVars(s)
variable.GetSessionVars(s).SetStatusFlag(mysql.ServerStatusAutocommit, true)
// session implements variable.GlobalSysVarAccessor. Bind it to ctx.
variable.BindGlobalSysVarAccessor(s, s)
// session implements variable.GlobalVarAccessor. Bind it to ctx.
variable.BindGlobalVarAccessor(s, s)
// session implements autocommit.Checker. Bind it to ctx
autocommit.BindAutocommitChecker(s, s)

View File

@ -23,6 +23,8 @@ type SessionVars struct {
Users map[string]string
// system variables
Systems map[string]string
// status variables
StatusVars map[string]string
// prepared statement
PreparedStmts map[string]interface{}
// prepared statement auto increment id
@ -58,6 +60,7 @@ func BindSessionVars(ctx context.Context) {
v := &SessionVars{
Users: make(map[string]string),
Systems: make(map[string]string),
StatusVars: make(map[string]string),
PreparedStmts: make(map[string]interface{}),
}

View File

@ -0,0 +1,391 @@
// Copyright 2015 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 variable
import (
"strings"
)
// StatusVars is global status vars map.
var StatusVars map[string]*SysVar
// GetStatusVar returns status var infomation for name.
func GetStatusVar(name string) *SysVar {
name = strings.ToLower(name)
return StatusVars[name]
}
func init() {
StatusVars = make(map[string]*SysVar)
for _, v := range defaultStatusVars {
StatusVars[v.Name] = v
}
}
var defaultStatusVars = []*SysVar{
{ScopeGlobal, "aborted_clients", "0"},
{ScopeGlobal, "binlog_cache_disk_use", "0"},
{ScopeGlobal, "binlog_cache_use", "0"},
{ScopeGlobal, "binlog_stmt_cache_disk_use", "0"},
{ScopeGlobal, "binlog_stmt_cache_use", "0"},
{ScopeGlobal | ScopeSession, "bytes_received", "2262"},
{ScopeGlobal | ScopeSession, "bytes_sent", "106142"},
{ScopeGlobal | ScopeSession, "com_admin_commands", "0"},
{ScopeGlobal | ScopeSession, "com_assign_to_keycache", "0"},
{ScopeGlobal | ScopeSession, "com_alter_db", "0"},
{ScopeGlobal | ScopeSession, "com_alter_db_upgrade", "0"},
{ScopeGlobal | ScopeSession, "com_alter_event", "0"},
{ScopeGlobal | ScopeSession, "com_alter_function", "0"},
{ScopeGlobal | ScopeSession, "com_alter_procedure", "0"},
{ScopeGlobal | ScopeSession, "com_alter_server", "0"},
{ScopeGlobal | ScopeSession, "com_alter_table", "0"},
{ScopeGlobal | ScopeSession, "com_alter_tablespace", "0"},
{ScopeGlobal | ScopeSession, "com_alter_user", "0"},
{ScopeGlobal | ScopeSession, "com_analyze", "0"},
{ScopeGlobal | ScopeSession, "com_begin", "0"},
{ScopeGlobal | ScopeSession, "com_binlog", "0"},
{ScopeGlobal | ScopeSession, "com_call_procedure", "0"},
{ScopeGlobal | ScopeSession, "com_change_db", "2"},
{ScopeGlobal | ScopeSession, "com_change_master", "0"},
{ScopeGlobal | ScopeSession, "com_change_repl_filter", "0"},
{ScopeGlobal | ScopeSession, "com_check", "0"},
{ScopeGlobal | ScopeSession, "com_checksum", "0"},
{ScopeGlobal | ScopeSession, "com_commit", "0"},
{ScopeGlobal | ScopeSession, "com_create_db", "1"},
{ScopeGlobal | ScopeSession, "com_create_event", "0"},
{ScopeGlobal | ScopeSession, "com_create_function", "0"},
{ScopeGlobal | ScopeSession, "com_create_index", "0"},
{ScopeGlobal | ScopeSession, "com_create_procedure", "0"},
{ScopeGlobal | ScopeSession, "com_create_server", "0"},
{ScopeGlobal | ScopeSession, "com_create_table", "1"},
{ScopeGlobal | ScopeSession, "com_create_trigger", "0"},
{ScopeGlobal | ScopeSession, "com_create_udf", "0"},
{ScopeGlobal | ScopeSession, "com_create_user", "0"},
{ScopeGlobal | ScopeSession, "com_create_view", "0"},
{ScopeGlobal | ScopeSession, "com_dealloc_sql", "0"},
{ScopeGlobal | ScopeSession, "com_delete", "0"},
{ScopeGlobal | ScopeSession, "com_delete_multi", "0"},
{ScopeGlobal | ScopeSession, "com_do", "0"},
{ScopeGlobal | ScopeSession, "com_drop_db", "0"},
{ScopeGlobal | ScopeSession, "com_drop_event", "0"},
{ScopeGlobal | ScopeSession, "com_drop_function", "0"},
{ScopeGlobal | ScopeSession, "com_drop_index", "0"},
{ScopeGlobal | ScopeSession, "com_drop_procedure", "0"},
{ScopeGlobal | ScopeSession, "com_drop_server", "0"},
{ScopeGlobal | ScopeSession, "com_drop_table", "0"},
{ScopeGlobal | ScopeSession, "com_drop_trigger", "0"},
{ScopeGlobal | ScopeSession, "com_drop_user", "0"},
{ScopeGlobal | ScopeSession, "com_drop_view", "0"},
{ScopeGlobal | ScopeSession, "com_empty_query", "0"},
{ScopeGlobal | ScopeSession, "com_execute_sql", "0"},
{ScopeGlobal | ScopeSession, "com_explain_other", "0"},
{ScopeGlobal | ScopeSession, "com_flush", "0"},
{ScopeGlobal | ScopeSession, "com_get_diagnostics", "0"},
{ScopeGlobal | ScopeSession, "com_grant", "0"},
{ScopeGlobal | ScopeSession, "com_ha_close", "0"},
{ScopeGlobal | ScopeSession, "com_ha_open", "0"},
{ScopeGlobal | ScopeSession, "com_ha_read", "0"},
{ScopeGlobal | ScopeSession, "com_help", "0"},
{ScopeGlobal | ScopeSession, "com_insert", "0"},
{ScopeGlobal | ScopeSession, "com_insert_select", "0"},
{ScopeGlobal | ScopeSession, "com_install_plugin", "0"},
{ScopeGlobal | ScopeSession, "com_kill", "0"},
{ScopeGlobal | ScopeSession, "com_load", "0"},
{ScopeGlobal | ScopeSession, "com_lock_tables", "0"},
{ScopeGlobal | ScopeSession, "com_optimize", "0"},
{ScopeGlobal | ScopeSession, "com_preload_keys", "0"},
{ScopeGlobal | ScopeSession, "com_prepare_sql", "0"},
{ScopeGlobal | ScopeSession, "com_purge", "0"},
{ScopeGlobal | ScopeSession, "com_purge_before_date", "0"},
{ScopeGlobal | ScopeSession, "com_release_savepoint", "0"},
{ScopeGlobal | ScopeSession, "com_rename_table", "0"},
{ScopeGlobal | ScopeSession, "com_rename_user", "0"},
{ScopeGlobal | ScopeSession, "com_repair", "0"},
{ScopeGlobal | ScopeSession, "com_replace", "0"},
{ScopeGlobal | ScopeSession, "com_replace_select", "0"},
{ScopeGlobal | ScopeSession, "com_reset", "0"},
{ScopeGlobal | ScopeSession, "com_resignal", "0"},
{ScopeGlobal | ScopeSession, "com_revoke", "0"},
{ScopeGlobal | ScopeSession, "com_revoke_all", "0"},
{ScopeGlobal | ScopeSession, "com_rollback", "0"},
{ScopeGlobal | ScopeSession, "com_rollback_to_savepoint", "0"},
{ScopeGlobal | ScopeSession, "com_savepoint", "0"},
{ScopeGlobal | ScopeSession, "com_select", "9"},
{ScopeGlobal | ScopeSession, "com_set_option", "0"},
{ScopeGlobal | ScopeSession, "com_signal", "0"},
{ScopeGlobal | ScopeSession, "com_show_binlog_events", "0"},
{ScopeGlobal | ScopeSession, "com_show_binlogs", "0"},
{ScopeGlobal | ScopeSession, "com_show_charsets", "0"},
{ScopeGlobal | ScopeSession, "com_show_collations", "0"},
{ScopeGlobal | ScopeSession, "com_show_create_db", "0"},
{ScopeGlobal | ScopeSession, "com_show_create_event", "0"},
{ScopeGlobal | ScopeSession, "com_show_create_func", "0"},
{ScopeGlobal | ScopeSession, "com_show_create_proc", "0"},
{ScopeGlobal | ScopeSession, "com_show_create_table", "0"},
{ScopeGlobal | ScopeSession, "com_show_create_trigger", "0"},
{ScopeGlobal | ScopeSession, "com_show_databases", "1"},
{ScopeGlobal | ScopeSession, "com_show_engine_logs", "0"},
{ScopeGlobal | ScopeSession, "com_show_engine_mutex", "0"},
{ScopeGlobal | ScopeSession, "com_show_engine_status", "0"},
{ScopeGlobal | ScopeSession, "com_show_events", "0"},
{ScopeGlobal | ScopeSession, "com_show_errors", "0"},
{ScopeGlobal | ScopeSession, "com_show_fields", "0"},
{ScopeGlobal | ScopeSession, "com_show_function_code", "0"},
{ScopeGlobal | ScopeSession, "com_show_function_status", "0"},
{ScopeGlobal | ScopeSession, "com_show_grants", "0"},
{ScopeGlobal | ScopeSession, "com_show_keys", "0"},
{ScopeGlobal | ScopeSession, "com_show_master_status", "0"},
{ScopeGlobal | ScopeSession, "com_show_open_tables", "0"},
{ScopeGlobal | ScopeSession, "com_show_plugins", "0"},
{ScopeGlobal | ScopeSession, "com_show_privileges", "0"},
{ScopeGlobal | ScopeSession, "com_show_procedure_code", "0"},
{ScopeGlobal | ScopeSession, "com_show_procedure_status", "0"},
{ScopeGlobal | ScopeSession, "com_show_processlist", "0"},
{ScopeGlobal | ScopeSession, "com_show_profile", "0"},
{ScopeGlobal | ScopeSession, "com_show_profiles", "0"},
{ScopeGlobal | ScopeSession, "com_show_relaylog_events", "0"},
{ScopeGlobal | ScopeSession, "com_show_slave_hosts", "0"},
{ScopeGlobal | ScopeSession, "com_show_slave_status", "0"},
{ScopeGlobal | ScopeSession, "com_show_status", "25"},
{ScopeGlobal | ScopeSession, "com_show_storage_engines", "0"},
{ScopeGlobal | ScopeSession, "com_show_table_status", "0"},
{ScopeGlobal | ScopeSession, "com_show_tables", "2"},
{ScopeGlobal | ScopeSession, "com_show_triggers", "0"},
{ScopeGlobal | ScopeSession, "com_show_variables", "4"},
{ScopeGlobal | ScopeSession, "com_show_warnings", "2"},
{ScopeGlobal | ScopeSession, "com_show_create_user", "0"},
{ScopeGlobal | ScopeSession, "com_shutdown", "0"},
{ScopeGlobal | ScopeSession, "com_slave_start", "0"},
{ScopeGlobal | ScopeSession, "com_slave_stop", "0"},
{ScopeGlobal | ScopeSession, "com_group_replication_start", "0"},
{ScopeGlobal | ScopeSession, "com_group_replication_stop", "0"},
{ScopeGlobal | ScopeSession, "com_stmt_execute", "0"},
{ScopeGlobal | ScopeSession, "com_stmt_close", "0"},
{ScopeGlobal | ScopeSession, "com_stmt_fetch", "0"},
{ScopeGlobal | ScopeSession, "com_stmt_prepare", "0"},
{ScopeGlobal | ScopeSession, "com_stmt_reset", "0"},
{ScopeGlobal | ScopeSession, "com_stmt_send_long_data", "0"},
{ScopeGlobal | ScopeSession, "com_truncate", "0"},
{ScopeGlobal | ScopeSession, "com_uninstall_plugin", "0"},
{ScopeGlobal | ScopeSession, "com_unlock_tables", "0"},
{ScopeGlobal | ScopeSession, "com_update", "0"},
{ScopeGlobal | ScopeSession, "com_update_multi", "0"},
{ScopeGlobal | ScopeSession, "com_xa_commit", "0"},
{ScopeGlobal | ScopeSession, "com_xa_end", "0"},
{ScopeGlobal | ScopeSession, "com_xa_prepare", "0"},
{ScopeGlobal | ScopeSession, "com_xa_recover", "0"},
{ScopeGlobal | ScopeSession, "com_xa_rollback", "0"},
{ScopeGlobal | ScopeSession, "com_xa_start", "0"},
{ScopeGlobal | ScopeSession, "com_stmt_reprepare", "0"},
{ScopeSession, "compression", "off"},
{ScopeGlobal, "connection_errors_accept", "0"},
{ScopeGlobal, "connection_errors_internal", "0"},
{ScopeGlobal, "connection_errors_max_connections", "0"},
{ScopeGlobal, "connection_errors_peer_address", "0"},
{ScopeGlobal, "connection_errors_select", "0"},
{ScopeGlobal, "connection_errors_tcpwrap", "0"},
{ScopeGlobal, "connections", "3"},
{ScopeGlobal | ScopeSession, "created_tmp_disk_tables", "0"},
{ScopeGlobal, "created_tmp_files", "6"},
{ScopeGlobal | ScopeSession, "created_tmp_tables", "3"},
{ScopeGlobal, "delayed_errors", "0"},
{ScopeGlobal, "delayed_insert_threads", "0"},
{ScopeGlobal, "delayed_writes", "0"},
{ScopeGlobal, "flush_commands", "1"},
{ScopeGlobal | ScopeSession, "handler_commit", "5"},
{ScopeGlobal | ScopeSession, "handler_delete", "0"},
{ScopeGlobal | ScopeSession, "handler_discover", "0"},
{ScopeGlobal | ScopeSession, "handler_external_lock", "265"},
{ScopeGlobal | ScopeSession, "handler_mrr_init", "0"},
{ScopeGlobal | ScopeSession, "handler_prepare", "0"},
{ScopeGlobal | ScopeSession, "handler_read_first", "8"},
{ScopeGlobal | ScopeSession, "handler_read_key", "6"},
{ScopeGlobal | ScopeSession, "handler_read_last", "0"},
{ScopeGlobal | ScopeSession, "handler_read_next", "1"},
{ScopeGlobal | ScopeSession, "handler_read_prev", "0"},
{ScopeGlobal | ScopeSession, "handler_read_rnd", "0"},
{ScopeGlobal | ScopeSession, "handler_read_rnd_next", "7642"},
{ScopeGlobal | ScopeSession, "handler_rollback", "0"},
{ScopeGlobal | ScopeSession, "handler_savepoint", "0"},
{ScopeGlobal | ScopeSession, "handler_savepoint_rollback", "0"},
{ScopeGlobal | ScopeSession, "handler_update", "0"},
{ScopeGlobal | ScopeSession, "handler_write", "6"},
{ScopeGlobal, "innodb_buffer_pool_dump_status", "notstarted"},
{ScopeGlobal, "innodb_buffer_pool_load_status", "Bufferpool(s)loadcom"},
{ScopeGlobal, "innodb_buffer_pool_resize_status", "notstarted"},
{ScopeGlobal, "innodb_buffer_pool_pages_data", "440"},
{ScopeGlobal, "innodb_buffer_pool_bytes_data", "7208960"},
{ScopeGlobal, "innodb_buffer_pool_pages_dirty", "0"},
{ScopeGlobal, "innodb_buffer_pool_bytes_dirty", "0"},
{ScopeGlobal, "innodb_buffer_pool_pages_flushed", "54"},
{ScopeGlobal, "innodb_buffer_pool_pages_free", "7751"},
{ScopeGlobal, "innodb_buffer_pool_pages_misc", "0"},
{ScopeGlobal, "innodb_buffer_pool_pages_total", "8191"},
{ScopeGlobal, "innodb_buffer_pool_read_ahead_rnd", "0"},
{ScopeGlobal, "innodb_buffer_pool_read_ahead", "0"},
{ScopeGlobal, "innodb_buffer_pool_read_ahead_evicted", "0"},
{ScopeGlobal, "innodb_buffer_pool_read_requests", "1466"},
{ScopeGlobal, "innodb_buffer_pool_reads", "402"},
{ScopeGlobal, "innodb_buffer_pool_wait_free", "0"},
{ScopeGlobal, "innodb_buffer_pool_write_requests", "400"},
{ScopeGlobal, "innodb_data_fsyncs", "24"},
{ScopeGlobal, "innodb_data_pending_fsyncs", "0"},
{ScopeGlobal, "innodb_data_pending_reads", "0"},
{ScopeGlobal, "innodb_data_pending_writes", "0"},
{ScopeGlobal, "innodb_data_read", "6656512"},
{ScopeGlobal, "innodb_data_reads", "426"},
{ScopeGlobal, "innodb_data_writes", "84"},
{ScopeGlobal, "innodb_data_written", "1232384"},
{ScopeGlobal, "innodb_dblwr_pages_written", "20"},
{ScopeGlobal, "innodb_dblwr_writes", "2"},
{ScopeGlobal, "innodb_log_waits", "0"},
{ScopeGlobal, "innodb_log_write_requests", "14"},
{ScopeGlobal, "innodb_log_writes", "8"},
{ScopeGlobal, "innodb_os_log_fsyncs", "12"},
{ScopeGlobal, "innodb_os_log_pending_fsyncs", "0"},
{ScopeGlobal, "innodb_os_log_pending_writes", "0"},
{ScopeGlobal, "innodb_os_log_written", "17920"},
{ScopeGlobal, "innodb_page_size", "16384"},
{ScopeGlobal, "innodb_pages_created", "39"},
{ScopeGlobal, "innodb_pages_read", "401"},
{ScopeGlobal, "innodb_pages_written", "54"},
{ScopeGlobal, "innodb_row_lock_current_waits", "0"},
{ScopeGlobal, "innodb_row_lock_time", "0"},
{ScopeGlobal, "innodb_row_lock_time_avg", "0"},
{ScopeGlobal, "innodb_row_lock_time_max", "0"},
{ScopeGlobal, "innodb_row_lock_waits", "0"},
{ScopeGlobal, "innodb_rows_deleted", "0"},
{ScopeGlobal, "innodb_rows_inserted", "0"},
{ScopeGlobal, "innodb_rows_read", "8"},
{ScopeGlobal, "innodb_rows_updated", "0"},
{ScopeGlobal, "innodb_num_open_files", "17"},
{ScopeGlobal, "innodb_truncated_status_writes", "0"},
{ScopeGlobal, "innodb_available_undo_logs", "128"},
{ScopeSession, "last_query_cost", "104.799000"},
{ScopeSession, "last_query_partial_plans", "1"},
{ScopeGlobal, "key_blocks_not_flushed", "0"},
{ScopeGlobal, "key_blocks_unused", "6695"},
{ScopeGlobal, "key_blocks_used", "3"},
{ScopeGlobal, "key_read_requests", "6"},
{ScopeGlobal, "key_reads", "3"},
{ScopeGlobal, "key_write_requests", "0"},
{ScopeGlobal, "key_writes", "0"},
{ScopeGlobal | ScopeSession, "locked_connects", "0"},
{ScopeGlobal | ScopeSession, "max_execution_time_exceeded", "0"},
{ScopeGlobal | ScopeSession, "max_execution_time_set", "0"},
{ScopeGlobal | ScopeSession, "max_execution_time_set_failed", "0"},
{ScopeGlobal, "max_used_connections", "1"},
{ScopeGlobal, "max_used_connections_time", "2015-11-0902:49:42"},
{ScopeGlobal, "not_flushed_delayed_rows", "0"},
{ScopeGlobal, "ongoing_anonymous_transaction_count", "0"},
{ScopeGlobal, "open_files", "14"},
{ScopeGlobal, "open_streams", "0"},
{ScopeGlobal, "open_table_definitions", "105"},
{ScopeGlobal | ScopeSession, "Open_tables", "101"},
{ScopeGlobal, "opened_files", "142"},
{ScopeGlobal | ScopeSession, "opened_table_definitions", "106"},
{ScopeGlobal | ScopeSession, "opened_tables", "108"},
{ScopeGlobal, "performance_schema_accounts_lost", "0"},
{ScopeGlobal, "performance_schema_cond_classes_lost", "0"},
{ScopeGlobal, "performance_schema_cond_instances_lost", "0"},
{ScopeGlobal, "performance_schema_digest_lost", "0"},
{ScopeGlobal, "performance_schema_file_classes_lost", "0"},
{ScopeGlobal, "performance_schema_file_handles_lost", "0"},
{ScopeGlobal, "performance_schema_file_instances_lost", "0"},
{ScopeGlobal, "performance_schema_hosts_lost", "0"},
{ScopeGlobal, "performance_schema_index_stat_lost", "0"},
{ScopeGlobal, "performance_schema_locker_lost", "0"},
{ScopeGlobal, "performance_schema_memory_classes_lost", "0"},
{ScopeGlobal, "performance_schema_metadata_lock_lost", "0"},
{ScopeGlobal, "performance_schema_mutex_classes_lost", "0"},
{ScopeGlobal, "performance_schema_mutex_instances_lost", "0"},
{ScopeGlobal, "performance_schema_nested_statement_lost", "0"},
{ScopeGlobal, "performance_schema_prepared_statements_lost", "0"},
{ScopeGlobal, "performance_schema_program_lost", "0"},
{ScopeGlobal, "performance_schema_rwlock_classes_lost", "0"},
{ScopeGlobal, "performance_schema_rwlock_instances_lost", "0"},
{ScopeGlobal, "performance_schema_session_connect_attrs_lost", "0"},
{ScopeGlobal, "performance_schema_socket_classes_lost", "0"},
{ScopeGlobal, "performance_schema_socket_instances_lost", "0"},
{ScopeGlobal, "performance_schema_stage_classes_lost", "0"},
{ScopeGlobal, "performance_schema_statement_classes_lost", "0"},
{ScopeGlobal, "performance_schema_table_handles_lost", "0"},
{ScopeGlobal, "performance_schema_table_instances_lost", "0"},
{ScopeGlobal, "performance_schema_table_lock_stat_lost", "0"},
{ScopeGlobal, "performance_schema_thread_classes_lost", "0"},
{ScopeGlobal, "performance_schema_thread_instances_lost", "0"},
{ScopeGlobal, "performance_schema_users_lost", "0"},
{ScopeGlobal, "prepared_stmt_count", "0"},
{ScopeGlobal, "qcache_free_blocks", "1"},
{ScopeGlobal, "qcache_free_memory", "1031832"},
{ScopeGlobal, "qcache_hits", "0"},
{ScopeGlobal, "qcache_inserts", "0"},
{ScopeGlobal, "qcache_lowmem_prunes", "0"},
{ScopeGlobal, "qcache_not_cached", "5"},
{ScopeGlobal, "qcache_queries_in_cache", "0"},
{ScopeGlobal, "qcache_total_blocks", "1"},
{ScopeGlobal | ScopeSession, "queries", "56"},
{ScopeGlobal | ScopeSession, "questions", "54"},
{ScopeGlobal | ScopeSession, "select_full_join", "0"},
{ScopeGlobal | ScopeSession, "select_full_range_join", "0"},
{ScopeGlobal | ScopeSession, "select_range", "0"},
{ScopeGlobal | ScopeSession, "select_range_check", "0"},
{ScopeGlobal | ScopeSession, "select_scan", "24"},
{ScopeGlobal, "slave_open_temp_tables", "0"},
{ScopeGlobal | ScopeSession, "slow_launch_threads", "0"},
{ScopeGlobal | ScopeSession, "slow_queries", "0"},
{ScopeGlobal | ScopeSession, "sort_merge_passes", "0"},
{ScopeGlobal | ScopeSession, "sort_range", "0"},
{ScopeGlobal | ScopeSession, "sort_rows", "0"},
{ScopeGlobal | ScopeSession, "sort_scan", "0"},
{ScopeGlobal, "ssl_accept_renegotiates", "0"},
{ScopeGlobal, "ssl_accepts", "0"},
{ScopeGlobal, "ssl_callback_cache_hits", "0"},
{ScopeGlobal | ScopeSession, "ssl_cipher", ""},
{ScopeGlobal | ScopeSession, "ssl_cipher_list", ""},
{ScopeGlobal, "ssl_client_connects", "0"},
{ScopeGlobal, "ssl_connect_renegotiates", "0"},
{ScopeGlobal, "ssl_ctx_verify_depth", "0"},
{ScopeGlobal, "ssl_ctx_verify_mode", "0"},
{ScopeGlobal | ScopeSession, "Ssl_default_timeout", "0"},
{ScopeGlobal, "ssl_finished_accepts", "0"},
{ScopeGlobal, "ssl_finished_connects", "0"},
{ScopeGlobal | ScopeSession, "ssl_server_not_after", ""},
{ScopeGlobal | ScopeSession, "ssl_server_not_before", ""},
{ScopeGlobal, "ssl_session_cache_hits", "0"},
{ScopeGlobal, "ssl_session_cache_misses", "0"},
{ScopeGlobal, "ssl_session_cache_mode", "NONE"},
{ScopeGlobal, "ssl_session_cache_overflows", "0"},
{ScopeGlobal, "ssl_session_cache_size", "0"},
{ScopeGlobal, "ssl_session_cache_timeouts", "0"},
{ScopeGlobal | ScopeSession, "ssl_sessions_reused", "0"},
{ScopeGlobal, "ssl_used_session_cache_entries", "0"},
{ScopeGlobal | ScopeSession, "ssl_verify_depth", "0"},
{ScopeGlobal | ScopeSession, "ssl_verify_mode", "0"},
{ScopeGlobal | ScopeSession, "ssl_version", ""},
{ScopeGlobal, "table_locks_immediate", "123"},
{ScopeGlobal, "table_locks_waited", "0"},
{ScopeGlobal | ScopeSession, "table_open_cache_hits", "28"},
{ScopeGlobal | ScopeSession, "table_open_cache_misses", "108"},
{ScopeGlobal | ScopeSession, "table_open_cache_overflows", "0"},
{ScopeGlobal, "tc_log_max_pages_used", "0"},
{ScopeGlobal, "tc_log_page_size", "0"},
{ScopeGlobal, "tc_log_page_waits", "0"},
{ScopeGlobal, "threads_cached", "0"},
{ScopeGlobal, "threads_connected", "1"},
{ScopeGlobal, "threads_created", "1"},
{ScopeGlobal, "threads_running", "1"},
{ScopeGlobal, "uptime", "15998"},
{ScopeGlobal, "uptime_since_flush_status", "15998"},
}

View File

@ -0,0 +1,31 @@
// Copyright 2015 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 variable
import (
. "github.com/pingcap/check"
)
var _ = Suite(&testStatusVarSuite{})
type testStatusVarSuite struct {
}
func (*testStatusVarSuite) TestStatusVar(c *C) {
f := GetStatusVar("aborted_clients")
c.Assert(f, NotNil)
f = GetStatusVar("wrong-var-name")
c.Assert(f, IsNil)
}

View File

@ -574,12 +574,16 @@ const (
CollationConnection = "collation_connection"
)
// GlobalSysVarAccessor is the interface for accessing global scope system variables.
type GlobalSysVarAccessor interface {
// GlobalVarAccessor is the interface for accessing global scope system and status variables.
type GlobalVarAccessor interface {
// GetGlobalSysVar gets the global system variable value for name.
GetGlobalSysVar(ctx context.Context, name string) (string, error)
// SetGlobalSysVar sets the global system variable name to value.
SetGlobalSysVar(ctx context.Context, name string, value string) error
// GetGlobalStatusVar gets the global status variable value for name.
GetGlobalStatusVar(ctx context.Context, name string) (string, error)
// SetGlobalStatusVar sets the global status variable name to value.
SetGlobalStatusVar(ctx context.Context, name string, value string) error
}
// globalSysVarAccessorKeyType is a dummy type to avoid naming collision in context.
@ -592,14 +596,14 @@ func (k globalSysVarAccessorKeyType) String() string {
const accessorKey globalSysVarAccessorKeyType = 0
// BindGlobalSysVarAccessor binds global sysvar accessor to context.
func BindGlobalSysVarAccessor(ctx context.Context, accessor GlobalSysVarAccessor) {
// BindGlobalVarAccessor binds global var accessor to context.
func BindGlobalVarAccessor(ctx context.Context, accessor GlobalVarAccessor) {
ctx.SetValue(accessorKey, accessor)
}
// GetGlobalSysVarAccessor gets accessor from ctx.
func GetGlobalSysVarAccessor(ctx context.Context) GlobalSysVarAccessor {
v, ok := ctx.Value(accessorKey).(GlobalSysVarAccessor)
// GetGlobalVarAccessor gets accessor from ctx.
func GetGlobalVarAccessor(ctx context.Context) GlobalVarAccessor {
v, ok := ctx.Value(accessorKey).(GlobalVarAccessor)
if !ok {
panic("Miss global sysvar accessor")
}

View File

@ -55,6 +55,7 @@ const (
ShowWarnings
ShowCharset
ShowVariables
ShowStatus
ShowCollation
ShowCreateTable
ShowGrants

View File

@ -24,6 +24,8 @@ import (
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/ddl"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/privilege"
"github.com/pingcap/tidb/rset"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/stmt"
@ -108,10 +110,34 @@ func (s *DropTableStmt) SetText(text string) {
// Exec implements the stmt.Statement Exec interface.
func (s *DropTableStmt) Exec(ctx context.Context) (rset.Recordset, error) {
var notExistTables []string
is := sessionctx.GetDomain(ctx).InfoSchema()
for _, ti := range s.TableIdents {
err := sessionctx.GetDomain(ctx).DDL().DropTable(ctx, ti.Full(ctx))
// TODO: we should return special error for table not exist, checking "not exist" is not enough,
// because some other errors may contain this error string too.
fullti := ti.Full(ctx)
schema, ok := is.SchemaByName(fullti.Schema)
if !ok {
// TODO: we should return special error for table not exist, checking "not exist" is not enough,
// because some other errors may contain this error string too.
notExistTables = append(notExistTables, ti.String())
continue
}
tb, err := is.TableByName(fullti.Schema, fullti.Name)
if err != nil && strings.HasSuffix(err.Error(), "not exist") {
notExistTables = append(notExistTables, ti.String())
continue
} else if err != nil {
return nil, errors.Trace(err)
}
// Check Privilege
privChecker := privilege.GetPrivilegeChecker(ctx)
hasPriv, err := privChecker.Check(ctx, schema, tb.Meta(), mysql.DropPriv)
if err != nil {
return nil, errors.Trace(err)
}
if !hasPriv {
return nil, errors.Errorf("You do not have the privilege to drop table %s.%s.", ti.Schema, ti.Name)
}
err = sessionctx.GetDomain(ctx).DDL().DropTable(ctx, fullti)
if terror.ErrorEqual(err, ddl.ErrNotExists) || terror.DatabaseNotExists.Equal(err) {
notExistTables = append(notExistTables, ti.String())
} else if err != nil {

View File

@ -100,7 +100,7 @@ func (s *SetStmt) Exec(ctx context.Context) (_ rset.Recordset, err error) {
log.Debug("Set sys/user variables")
sessionVars := variable.GetSessionVars(ctx)
globalVars := variable.GetGlobalSysVarAccessor(ctx)
globalVars := variable.GetGlobalVarAccessor(ctx)
for _, v := range s.Variables {
// Variable is case insensitive, we use lower case.
name := strings.ToLower(v.Name)

View File

@ -451,7 +451,8 @@ func (s *testKVSuite) TestConditionIfNotExist(c *C) {
}()
}
wg.Wait()
c.Assert(success, Greater, int64(1))
// At least one txn can success.
c.Assert(success, Greater, int64(0))
// Clean up
txn, err := s.s.Begin()

View File

@ -28,6 +28,10 @@ var (
CommitNotInTransaction = ClassExecutor.New(CodeCommitNotInTransaction, "commit not in transaction")
RollbackNotInTransaction = ClassExecutor.New(CodeRollbackNotInTransaction, "rollback not in transaction")
ExecResultIsEmpty = ClassExecutor.New(CodeExecResultIsEmpty, "exec result is empty")
UnknownStatusVar = ClassVariable.New(CodeUnknownStatusVar, "unknown status variable")
UnknownSystemVar = ClassVariable.New(CodeUnknownSystemVar, "unknown system variable")
)
// ErrCode represents a specific error type in a error class.
@ -44,6 +48,7 @@ const (
const (
CodeCommitNotInTransaction ErrCode = iota + 1
CodeRollbackNotInTransaction
CodeExecResultIsEmpty
)
// KV error codes.
@ -52,6 +57,12 @@ const (
CodeNoDataForHandle
)
// Variable error codes.
const (
CodeUnknownStatusVar ErrCode = iota + 1
CodeUnknownSystemVar
)
// ErrClass represents a class of errors.
type ErrClass int
@ -63,6 +74,7 @@ const (
ClassExecutor
ClassKV
ClassServer
ClassVariable
// Add more as needed.
)

View File

@ -16,11 +16,11 @@ package mock
import (
"fmt"
"strings"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/terror"
)
var _ context.Context = (*Context)(nil)
@ -57,22 +57,39 @@ func (c *Context) FinishTxn(rollback bool) error {
return nil
}
// GetGlobalSysVar implements GlobalSysVarAccessor GetGlobalSysVar interface.
func (c *Context) GetGlobalSysVar(ctx context.Context, name string) (string, error) {
sysvars := variable.SysVars
v, ok := sysvars[strings.ToLower(name)]
if !ok {
return "", nil
// GetGlobalStatusVar implements GlobalVarAccessor GetGlobalStatusVar interface.
func (c *Context) GetGlobalStatusVar(ctx context.Context, name string) (string, error) {
v := variable.GetStatusVar(name)
if v == nil {
return "", terror.UnknownStatusVar.Gen("unknown status variable: %s", name)
}
return v.Value, nil
}
// SetGlobalSysVar implements GlobalSysVarAccessor SetGlobalSysVar interface.
// SetGlobalStatusVar implements GlobalVarAccessor SetGlobalStatusVar interface.
func (c *Context) SetGlobalStatusVar(ctx context.Context, name string, value string) error {
v := variable.GetStatusVar(name)
if v == nil {
return terror.UnknownStatusVar.Gen("unknown status variable: %s", name)
}
v.Value = value
return nil
}
// GetGlobalSysVar implements GlobalVarAccessor GetGlobalSysVar interface.
func (c *Context) GetGlobalSysVar(ctx context.Context, name string) (string, error) {
v := variable.GetSysVar(name)
if v == nil {
return "", terror.UnknownSystemVar.Gen("unknown sys variable: %s", name)
}
return v.Value, nil
}
// SetGlobalSysVar implements GlobalVarAccessor SetGlobalSysVar interface.
func (c *Context) SetGlobalSysVar(ctx context.Context, name string, value string) error {
sysvars := variable.SysVars
v, ok := sysvars[strings.ToLower(name)]
if !ok {
return fmt.Errorf("Unknown sys var: %s", name)
v := variable.GetSysVar(name)
if v == nil {
return terror.UnknownSystemVar.Gen("unknown sys variable: %s", name)
}
v.Value = value
return nil

View File

@ -21,19 +21,11 @@ import (
// RoundFloat uses default rounding mode, see http://www.gnu.org/software/libc/manual/html_node/Rounding.html
// so we will choose the even number if the result is midway between two representable value.
// e.g, 1.5 -> 2, 2.5 -> 2.
func RoundFloat(val float64) float64 {
v, frac := math.Modf(val)
if val >= 0.0 {
if frac > 0.5 || (frac == 0.5 && uint64(v)%2 != 0) {
v += 1.0
}
} else {
if frac < -0.5 || (frac == -0.5 && uint64(v)%2 != 0) {
v -= 1.0
}
func RoundFloat(f float64) float64 {
if math.Remainder(f, 1.0) < 0 {
return math.Ceil(f)
}
return v
return math.Floor(f)
}
func getMaxFloat(flen int, decimal int) float64 {