func HasDefaultValue(s Session, key string) (bool, interface{}) {
	typ, val := s.Get(key)
	if cfg, ok := DefaultSessionConfig()[key]; ok {
		return (cfg.Typ == typ && cfg.Value == val), val
	}
	return false, val
}
HasDefaultValue checks if session variable value is the default one.
package sql
import (
	"context"
	"fmt"
	"io"
	"math"
	"sync"
	"time"
	opentracing "github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/log"
)
type key uint
const (
	QueryKey key = iota
)
type Client struct {
	User string
	Address string
}
type Session interface {
	Address() string
	Client() Client
	Set(key string, typ Type, value interface{})
	Get(key string) (Type, interface{})
	GetAll() map[string]TypedValue
	ID() uint32
	Warn(warn *Warning)
	Warnings() []*Warning
	ClearWarnings()
	WarningCount() uint16
}
type BaseSession struct {
	id       uint32
	addr     string
	client   Client
	mu       sync.RWMutex
	config   map[string]TypedValue
	warnings []*Warning
	warncnt  uint16
}
func (s *BaseSession) Address() string { return s.addr }
func (s *BaseSession) Client() Client { return s.client }
func (s *BaseSession) Set(key string, typ Type, value interface{}) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.config[key] = TypedValue{typ, value}
}
func (s *BaseSession) Get(key string) (Type, interface{}) {
	s.mu.RLock()
	defer s.mu.RUnlock()
	v, ok := s.config[key]
	if !ok {
		return Null, nil
	}
	return v.Typ, v.Value
}
func (s *BaseSession) GetAll() map[string]TypedValue {
	m := make(map[string]TypedValue)
	s.mu.RLock()
	defer s.mu.RUnlock()
	for k, v := range s.config {
		m[k] = v
	}
	return m
}
func (s *BaseSession) ID() uint32 { return s.id }
func (s *BaseSession) Warn(warn *Warning) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.warnings = append(s.warnings, warn)
}
func (s *BaseSession) Warnings() []*Warning {
	s.mu.RLock()
	defer s.mu.RUnlock()
	n := len(s.warnings)
	warns := make([]*Warning, n)
	for i := 0; i < n; i++ {
		warns[i] = s.warnings[n-i-1]
	}
	return warns
}
func (s *BaseSession) ClearWarnings() {
	s.mu.Lock()
	defer s.mu.Unlock()
	cnt := uint16(len(s.warnings))
	if s.warncnt == cnt {
		if s.warnings != nil {
			s.warnings = s.warnings[:0]
		}
		s.warncnt = 0
	} else {
		s.warncnt = cnt
	}
}
func (s *BaseSession) WarningCount() uint16 {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return uint16(len(s.warnings))
}
type (
	TypedValue struct {
		Typ   Type
		Value interface{}
	}
	Warning struct {
		Level   string
		Message string
		Code    int
	}
)
func DefaultSessionConfig() map[string]TypedValue {
	return map[string]TypedValue{
		"auto_increment_increment": TypedValue{Int64, int64(1)},
		"time_zone":                TypedValue{Text, time.Local.String()},
		"system_time_zone":         TypedValue{Text, time.Local.String()},
		"max_allowed_packet":       TypedValue{Int32, math.MaxInt32},
		"sql_mode":                 TypedValue{Text, ""},
		"gtid_mode":                TypedValue{Int32, int32(0)},
		"collation_database":       TypedValue{Text, "utf8_bin"},
		"ndbinfo_version":          TypedValue{Text, ""},
		"sql_select_limit":         TypedValue{Int32, math.MaxInt32},
		"transaction_isolation":    TypedValue{Text, "READ UNCOMMITTED"},
		"version":                  TypedValue{Text, ""},
		"version_comment":          TypedValue{Text, ""},
	}
}