1
0
Fork 0
forked from forgejo/forgejo

Integrate public as bindata optionally (#293)

* Dropped unused codekit config

* Integrated dynamic and static bindata for public

* Ignore public bindata

* Add a general generate make task

* Integrated flexible public assets into web command

* Updated vendoring, added all missiong govendor deps

* Made the linter happy with the bindata and dynamic code

* Moved public bindata definition to modules directory

* Ignoring the new bindata path now

* Updated to the new public modules import path

* Updated public bindata command and drop the new prefix
This commit is contained in:
Thomas Boerger 2016-11-29 17:26:36 +01:00 committed by Lunny Xiao
parent 4680c349dd
commit b6a95a8cb3
691 changed files with 305318 additions and 1272 deletions

50
vendor/github.com/pingcap/go-hbase/LICENSE generated vendored Normal file
View file

@ -0,0 +1,50 @@
The MIT License (MIT)
Copyright (c) 2015 dongxu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Copyright (c) 2014 Bryan Peterson. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

14
vendor/github.com/pingcap/go-hbase/README.md generated vendored Normal file
View file

@ -0,0 +1,14 @@
#go-hbase
[![Build Status](https://travis-ci.org/pingcap/go-hbase.svg)](https://travis-ci.org/pingcap/go-hbase)
Derived from [Lazyshot/go-hbase](https://github.com/Lazyshot/go-hbase). Add some new features and fix some bugs.
## New Features
1. Coprocessor EndPoint call.
2. Goroutine-safe.
3. Admin commands: Create/Disable/Drop table.
4. Pipelined RPC.
Support HBase >= 0.98.5

101
vendor/github.com/pingcap/go-hbase/action.go generated vendored Normal file
View file

@ -0,0 +1,101 @@
package hbase
import (
pb "github.com/golang/protobuf/proto"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase/proto"
)
type action interface {
ToProto() pb.Message
}
func (c *client) innerCall(table, row []byte, action action, useCache bool) (*call, error) {
region, err := c.LocateRegion(table, row, useCache)
if err != nil {
return nil, errors.Trace(err)
}
conn, err := c.getClientConn(region.Server)
if err != nil {
return nil, errors.Trace(err)
}
regionSpecifier := &proto.RegionSpecifier{
Type: proto.RegionSpecifier_REGION_NAME.Enum(),
Value: []byte(region.Name),
}
var cl *call
switch a := action.(type) {
case *Get:
cl = newCall(&proto.GetRequest{
Region: regionSpecifier,
Get: a.ToProto().(*proto.Get),
})
case *Put, *Delete:
cl = newCall(&proto.MutateRequest{
Region: regionSpecifier,
Mutation: a.ToProto().(*proto.MutationProto),
})
case *CoprocessorServiceCall:
cl = newCall(&proto.CoprocessorServiceRequest{
Region: regionSpecifier,
Call: a.ToProto().(*proto.CoprocessorServiceCall),
})
default:
return nil, errors.Errorf("Unknown action - %T - %v", action, action)
}
err = conn.call(cl)
if err != nil {
// If failed, remove bad server conn cache.
cachedKey := cachedConnKey(region.Server, ClientService)
delete(c.cachedConns, cachedKey)
return nil, errors.Trace(err)
}
return cl, nil
}
func (c *client) innerDo(table, row []byte, action action, useCache bool) (pb.Message, error) {
// Try to create and send a new resuqest call.
cl, err := c.innerCall(table, row, action, useCache)
if err != nil {
log.Warnf("inner call failed - %v", errors.ErrorStack(err))
return nil, errors.Trace(err)
}
// Wait and receive the result.
return <-cl.responseCh, nil
}
func (c *client) do(table, row []byte, action action, useCache bool) (pb.Message, error) {
var (
result pb.Message
err error
)
LOOP:
for i := 0; i < c.maxRetries; i++ {
result, err = c.innerDo(table, row, action, useCache)
if err == nil {
switch r := result.(type) {
case *exception:
err = errors.New(r.msg)
// If get an execption response, clean old region cache.
c.CleanRegionCache(table)
default:
break LOOP
}
}
useCache = false
log.Warnf("Retrying action for the %d time(s), error - %v", i+1, errors.ErrorStack(err))
retrySleep(i + 1)
}
return result, errors.Trace(err)
}

340
vendor/github.com/pingcap/go-hbase/admin.go generated vendored Normal file
View file

@ -0,0 +1,340 @@
package hbase
import (
"sort"
"strconv"
"strings"
"time"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase/proto"
)
const defaultNS = "default"
type TableName struct {
namespace string
name string
}
func newTableNameWithDefaultNS(tblName string) TableName {
return TableName{
namespace: defaultNS,
name: tblName,
}
}
type TableDescriptor struct {
name TableName
attrs map[string][]byte
cfs []*ColumnFamilyDescriptor
}
func NewTableDesciptor(tblName string) *TableDescriptor {
ret := &TableDescriptor{
name: newTableNameWithDefaultNS(tblName),
attrs: map[string][]byte{},
}
ret.AddAddr("IS_META", "false")
return ret
}
func (c *TableDescriptor) AddAddr(attrName string, val string) {
c.attrs[attrName] = []byte(val)
}
func (t *TableDescriptor) AddColumnDesc(cf *ColumnFamilyDescriptor) {
for _, c := range t.cfs {
if c.name == cf.name {
return
}
}
t.cfs = append(t.cfs, cf)
}
type ColumnFamilyDescriptor struct {
name string
attrs map[string][]byte
}
func (c *ColumnFamilyDescriptor) AddAttr(attrName string, val string) {
c.attrs[attrName] = []byte(val)
}
// Themis will use VERSIONS=1 for some hook.
func NewColumnFamilyDescriptor(name string) *ColumnFamilyDescriptor {
return newColumnFamilyDescriptor(name, 1)
}
func newColumnFamilyDescriptor(name string, versionsNum int) *ColumnFamilyDescriptor {
versions := strconv.Itoa(versionsNum)
ret := &ColumnFamilyDescriptor{
name: name,
attrs: make(map[string][]byte),
}
// add default attrs
ret.AddAttr("DATA_BLOCK_ENCODING", "NONE")
ret.AddAttr("BLOOMFILTER", "ROW")
ret.AddAttr("REPLICATION_SCOPE", "0")
ret.AddAttr("COMPRESSION", "NONE")
ret.AddAttr("VERSIONS", versions)
ret.AddAttr("TTL", "2147483647") // 1 << 31
ret.AddAttr("MIN_VERSIONS", "0")
ret.AddAttr("KEEP_DELETED_CELLS", "false")
ret.AddAttr("BLOCKSIZE", "65536")
ret.AddAttr("IN_MEMORY", "false")
ret.AddAttr("BLOCKCACHE", "true")
return ret
}
func getPauseTime(retry int) int64 {
if retry >= len(retryPauseTime) {
retry = len(retryPauseTime) - 1
}
if retry < 0 {
retry = 0
}
return retryPauseTime[retry] * defaultRetryWaitMs
}
func (c *client) CreateTable(t *TableDescriptor, splits [][]byte) error {
req := &proto.CreateTableRequest{}
schema := &proto.TableSchema{}
sort.Sort(BytesSlice(splits))
schema.TableName = &proto.TableName{
Qualifier: []byte(t.name.name),
Namespace: []byte(t.name.namespace),
}
for k, v := range t.attrs {
schema.Attributes = append(schema.Attributes, &proto.BytesBytesPair{
First: []byte(k),
Second: []byte(v),
})
}
for _, c := range t.cfs {
cf := &proto.ColumnFamilySchema{
Name: []byte(c.name),
}
for k, v := range c.attrs {
cf.Attributes = append(cf.Attributes, &proto.BytesBytesPair{
First: []byte(k),
Second: []byte(v),
})
}
schema.ColumnFamilies = append(schema.ColumnFamilies, cf)
}
req.TableSchema = schema
req.SplitKeys = splits
ch, err := c.adminAction(req)
if err != nil {
return errors.Trace(err)
}
resp := <-ch
switch r := resp.(type) {
case *exception:
return errors.New(r.msg)
}
// wait and check
for retry := 0; retry < defaultMaxActionRetries*retryLongerMultiplier; retry++ {
regCnt := 0
numRegs := len(splits) + 1
err = c.metaScan(t.name.name, func(r *RegionInfo) (bool, error) {
if !(r.Offline || r.Split) && len(r.Server) > 0 && r.TableName == t.name.name {
regCnt++
}
return true, nil
})
if err != nil {
return errors.Trace(err)
}
if regCnt == numRegs {
return nil
}
log.Warnf("Retrying create table for the %d time(s)", retry+1)
time.Sleep(time.Duration(getPauseTime(retry)) * time.Millisecond)
}
return errors.New("create table timeout")
}
func (c *client) DisableTable(tblName string) error {
req := &proto.DisableTableRequest{
TableName: &proto.TableName{
Qualifier: []byte(tblName),
Namespace: []byte(defaultNS),
},
}
ch, err := c.adminAction(req)
if err != nil {
return errors.Trace(err)
}
resp := <-ch
switch r := resp.(type) {
case *exception:
return errors.New(r.msg)
}
return nil
}
func (c *client) EnableTable(tblName string) error {
req := &proto.EnableTableRequest{
TableName: &proto.TableName{
Qualifier: []byte(tblName),
Namespace: []byte(defaultNS),
},
}
ch, err := c.adminAction(req)
if err != nil {
return errors.Trace(err)
}
resp := <-ch
switch r := resp.(type) {
case *exception:
return errors.New(r.msg)
}
return nil
}
func (c *client) DropTable(tblName string) error {
req := &proto.DeleteTableRequest{
TableName: &proto.TableName{
Qualifier: []byte(tblName),
Namespace: []byte(defaultNS),
},
}
ch, err := c.adminAction(req)
if err != nil {
return errors.Trace(err)
}
resp := <-ch
switch r := resp.(type) {
case *exception:
return errors.New(r.msg)
}
return nil
}
func (c *client) metaScan(tbl string, fn func(r *RegionInfo) (bool, error)) error {
scan := NewScan(metaTableName, 0, c)
defer scan.Close()
scan.StartRow = []byte(tbl)
scan.StopRow = nextKey([]byte(tbl))
for {
r := scan.Next()
if r == nil || scan.Closed() {
break
}
region, err := c.parseRegion(r)
if err != nil {
return errors.Trace(err)
}
if more, err := fn(region); !more || err != nil {
return errors.Trace(err)
}
}
return nil
}
func (c *client) TableExists(tbl string) (bool, error) {
found := false
err := c.metaScan(tbl, func(region *RegionInfo) (bool, error) {
if region.TableName == tbl {
found = true
return false, nil
}
return true, nil
})
if err != nil {
return false, errors.Trace(err)
}
return found, nil
}
// Split splits region.
// tblOrRegion table name or region(<tbl>,<endKey>,<timestamp>.<md5>).
// splitPoint which is a key, leave "" if want to split each region automatically.
func (c *client) Split(tblOrRegion, splitPoint string) error {
// Extract table name from supposing regionName.
tbls := strings.SplitN(tblOrRegion, ",", 2)
tbl := tbls[0]
found := false
var foundRegion *RegionInfo
err := c.metaScan(tbl, func(region *RegionInfo) (bool, error) {
if region != nil && region.Name == tblOrRegion {
found = true
foundRegion = region
return false, nil
}
return true, nil
})
if err != nil {
return errors.Trace(err)
}
// This is a region name, split it directly.
if found {
return c.split(foundRegion, []byte(splitPoint))
}
// This is a table name.
tbl = tblOrRegion
regions, err := c.GetRegions([]byte(tbl), false)
if err != nil {
return errors.Trace(err)
}
// Split each region.
for _, region := range regions {
err := c.split(region, []byte(splitPoint))
if err != nil {
return errors.Trace(err)
}
}
return nil
}
func (c *client) split(region *RegionInfo, splitPoint []byte) error {
// Not in this region, skip it.
if len(splitPoint) > 0 && !findKey(region, splitPoint) {
return nil
}
c.CleanRegionCache([]byte(region.TableName))
rs := NewRegionSpecifier(region.Name)
req := &proto.SplitRegionRequest{
Region: rs,
}
if len(splitPoint) > 0 {
req.SplitPoint = splitPoint
}
// Empty response.
_, err := c.regionAction(region.Server, req)
if err != nil {
return errors.Trace(err)
}
return nil
}

100
vendor/github.com/pingcap/go-hbase/call.go generated vendored Normal file
View file

@ -0,0 +1,100 @@
package hbase
import (
"strings"
pb "github.com/golang/protobuf/proto"
"github.com/pingcap/go-hbase/proto"
)
type call struct {
id uint32
methodName string
request pb.Message
responseBuffer pb.Message
responseCh chan pb.Message
}
type exception struct {
msg string
}
func isNotInRegionError(err error) bool {
return strings.Contains(err.Error(), "org.apache.hadoop.hbase.NotServingRegionException")
}
func isUnknownScannerError(err error) bool {
return strings.Contains(err.Error(), "org.apache.hadoop.hbase.UnknownScannerException")
}
func (m *exception) Reset() { *m = exception{} }
func (m *exception) String() string { return m.msg }
func (m *exception) ProtoMessage() {}
func newCall(request pb.Message) *call {
var responseBuffer pb.Message
var methodName string
switch request.(type) {
case *proto.GetRequest:
responseBuffer = &proto.GetResponse{}
methodName = "Get"
case *proto.MutateRequest:
responseBuffer = &proto.MutateResponse{}
methodName = "Mutate"
case *proto.ScanRequest:
responseBuffer = &proto.ScanResponse{}
methodName = "Scan"
case *proto.GetTableDescriptorsRequest:
responseBuffer = &proto.GetTableDescriptorsResponse{}
methodName = "GetTableDescriptors"
case *proto.CoprocessorServiceRequest:
responseBuffer = &proto.CoprocessorServiceResponse{}
methodName = "ExecService"
case *proto.CreateTableRequest:
responseBuffer = &proto.CreateTableResponse{}
methodName = "CreateTable"
case *proto.DisableTableRequest:
responseBuffer = &proto.DisableTableResponse{}
methodName = "DisableTable"
case *proto.EnableTableRequest:
responseBuffer = &proto.EnableTableResponse{}
methodName = "EnableTable"
case *proto.DeleteTableRequest:
responseBuffer = &proto.DeleteTableResponse{}
methodName = "DeleteTable"
case *proto.MultiRequest:
responseBuffer = &proto.MultiResponse{}
methodName = "Multi"
case *proto.SplitRegionRequest:
responseBuffer = &proto.SplitRegionResponse{}
methodName = "SplitRegion"
}
return &call{
methodName: methodName,
request: request,
responseBuffer: responseBuffer,
responseCh: make(chan pb.Message, 1),
}
}
func (c *call) complete(err error, response []byte) {
defer close(c.responseCh)
if err != nil {
c.responseCh <- &exception{
msg: err.Error(),
}
return
}
err = pb.Unmarshal(response, c.responseBuffer)
if err != nil {
c.responseCh <- &exception{
msg: err.Error(),
}
return
}
c.responseCh <- c.responseBuffer
}

454
vendor/github.com/pingcap/go-hbase/client.go generated vendored Normal file
View file

@ -0,0 +1,454 @@
package hbase
import (
"bytes"
"crypto/md5"
"encoding/binary"
"encoding/hex"
"fmt"
"sync"
"time"
pb "github.com/golang/protobuf/proto"
"github.com/juju/errors"
"github.com/ngaut/go-zookeeper/zk"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase/proto"
)
const (
zkRootRegionPath = "/meta-region-server"
zkMasterAddrPath = "/master"
magicHeadByte = 0xff
magicHeadSize = 1
idLengthSize = 4
md5HexSize = 32
servernameSeparator = ","
rpcTimeout = 30000
pingTimeout = 30000
callTimeout = 5000
defaultMaxActionRetries = 3
// Some operations can take a long time such as disable of big table.
// numRetries is for 'normal' stuff... Multiply by this factor when
// want to wait a long time.
retryLongerMultiplier = 31
socketDefaultRetryWaitMs = 200
defaultRetryWaitMs = 100
// always >= any unix timestamp(hbase version)
beyondMaxTimestamp = "99999999999999"
)
var (
hbaseHeaderBytes []byte = []byte("HBas")
metaTableName []byte = []byte("hbase:meta")
metaRegionName []byte = []byte("hbase:meta,,1")
)
var retryPauseTime = []int64{1, 2, 3, 5, 10, 20, 40, 100, 100, 100, 100, 200, 200}
type RegionInfo struct {
Server string
StartKey []byte
EndKey []byte
Name string
Ts string
TableNamespace string
TableName string
Offline bool
Split bool
}
type tableInfo struct {
tableName string
families []string
}
// export client interface
type HBaseClient interface {
Get(tbl string, g *Get) (*ResultRow, error)
Put(tbl string, p *Put) (bool, error)
Delete(tbl string, d *Delete) (bool, error)
TableExists(tbl string) (bool, error)
DropTable(t string) error
DisableTable(t string) error
EnableTable(t string) error
CreateTable(t *TableDescriptor, splits [][]byte) error
ServiceCall(table string, call *CoprocessorServiceCall) (*proto.CoprocessorServiceResponse, error)
LocateRegion(table, row []byte, useCache bool) (*RegionInfo, error)
GetRegions(table []byte, useCache bool) ([]*RegionInfo, error)
Split(tblOrRegion, splitPoint string) error
CleanRegionCache(table []byte)
CleanAllRegionCache()
Close() error
}
// hbase client implemetation
var _ HBaseClient = (*client)(nil)
type client struct {
mu sync.RWMutex // for read/update region info
zkClient *zk.Conn
zkHosts []string
zkRoot string
prefetched map[string]bool
cachedConns map[string]*connection
cachedRegionInfo map[string]map[string]*RegionInfo
maxRetries int
rootServerName *proto.ServerName
masterServerName *proto.ServerName
}
func serverNameToAddr(server *proto.ServerName) string {
return fmt.Sprintf("%s:%d", server.GetHostName(), server.GetPort())
}
func cachedConnKey(addr string, srvType ServiceType) string {
return fmt.Sprintf("%s|%d", addr, srvType)
}
func NewClient(zkHosts []string, zkRoot string) (HBaseClient, error) {
cl := &client{
zkHosts: zkHosts,
zkRoot: zkRoot,
cachedConns: make(map[string]*connection),
cachedRegionInfo: make(map[string]map[string]*RegionInfo),
prefetched: make(map[string]bool),
maxRetries: defaultMaxActionRetries,
}
err := cl.init()
if err != nil {
return nil, errors.Trace(err)
}
return cl, nil
}
func (c *client) decodeMeta(data []byte) (*proto.ServerName, error) {
if data[0] != magicHeadByte {
return nil, errors.New("unknown packet")
}
var n int32
err := binary.Read(bytes.NewBuffer(data[1:]), binary.BigEndian, &n)
if err != nil {
return nil, errors.Trace(err)
}
dataOffset := magicHeadSize + idLengthSize + int(n)
data = data[(dataOffset + 4):]
var mrs proto.MetaRegionServer
err = pb.Unmarshal(data, &mrs)
if err != nil {
return nil, errors.Trace(err)
}
return mrs.GetServer(), nil
}
// init and get root region server addr and master addr
func (c *client) init() error {
zkclient, _, err := zk.Connect(c.zkHosts, time.Second*30)
if err != nil {
return errors.Trace(err)
}
c.zkClient = zkclient
res, _, _, err := c.zkClient.GetW(c.zkRoot + zkRootRegionPath)
if err != nil {
return errors.Trace(err)
}
c.rootServerName, err = c.decodeMeta(res)
if err != nil {
return errors.Trace(err)
}
log.Debug("connect root region server...", c.rootServerName)
serverAddr := serverNameToAddr(c.rootServerName)
conn, err := newConnection(serverAddr, ClientService)
if err != nil {
return errors.Trace(err)
}
// Set buffered regionserver conn.
cachedKey := cachedConnKey(serverAddr, ClientService)
c.cachedConns[cachedKey] = conn
res, _, _, err = c.zkClient.GetW(c.zkRoot + zkMasterAddrPath)
if err != nil {
return errors.Trace(err)
}
c.masterServerName, err = c.decodeMeta(res)
if err != nil {
return errors.Trace(err)
}
return nil
}
// get connection
func (c *client) getConn(addr string, srvType ServiceType) (*connection, error) {
connKey := cachedConnKey(addr, srvType)
c.mu.RLock()
conn, ok := c.cachedConns[connKey]
c.mu.RUnlock()
if ok {
return conn, nil
}
var err error
conn, err = newConnection(addr, srvType)
if err != nil {
return nil, errors.Errorf("create new connection failed - %v", errors.ErrorStack(err))
}
c.mu.Lock()
c.cachedConns[connKey] = conn
c.mu.Unlock()
return conn, nil
}
func (c *client) getAdminConn(addr string) (*connection, error) {
return c.getConn(addr, AdminService)
}
func (c *client) getClientConn(addr string) (*connection, error) {
return c.getConn(addr, ClientService)
}
func (c *client) getMasterConn() (*connection, error) {
return c.getConn(serverNameToAddr(c.masterServerName), MasterService)
}
func (c *client) doAction(conn *connection, req pb.Message) (chan pb.Message, error) {
cl := newCall(req)
err := conn.call(cl)
if err != nil {
return nil, errors.Trace(err)
}
return cl.responseCh, nil
}
func (c *client) adminAction(req pb.Message) (chan pb.Message, error) {
conn, err := c.getMasterConn()
if err != nil {
return nil, errors.Trace(err)
}
return c.doAction(conn, req)
}
func (c *client) regionAction(addr string, req pb.Message) (chan pb.Message, error) {
conn, err := c.getAdminConn(addr)
if err != nil {
return nil, errors.Trace(err)
}
return c.doAction(conn, req)
}
// http://stackoverflow.com/questions/27602013/correct-way-to-get-region-name-by-using-hbase-api
func (c *client) createRegionName(table, startKey []byte, id string, newFormat bool) []byte {
if len(startKey) == 0 {
startKey = make([]byte, 1)
}
b := bytes.Join([][]byte{table, startKey, []byte(id)}, []byte{','})
if newFormat {
m := md5.Sum(b)
mhex := []byte(hex.EncodeToString(m[:]))
b = append(bytes.Join([][]byte{b, mhex}, []byte{'.'}), '.')
}
return b
}
func (c *client) parseRegion(rr *ResultRow) (*RegionInfo, error) {
regionInfoCol, ok := rr.Columns["info:regioninfo"]
if !ok {
return nil, errors.Errorf("Unable to parse region location (no regioninfo column): %#v", rr)
}
offset := bytes.Index(regionInfoCol.Value, []byte("PBUF")) + 4
regionInfoBytes := regionInfoCol.Value[offset:]
var info proto.RegionInfo
err := pb.Unmarshal(regionInfoBytes, &info)
if err != nil {
return nil, errors.Errorf("Unable to parse region location: %#v", err)
}
ri := &RegionInfo{
StartKey: info.GetStartKey(),
EndKey: info.GetEndKey(),
Name: bytes.NewBuffer(rr.Row).String(),
TableNamespace: string(info.GetTableName().GetNamespace()),
TableName: string(info.GetTableName().GetQualifier()),
Offline: info.GetOffline(),
Split: info.GetSplit(),
}
if v, ok := rr.Columns["info:server"]; ok {
ri.Server = string(v.Value)
}
return ri, nil
}
func (c *client) getMetaRegion() *RegionInfo {
return &RegionInfo{
StartKey: []byte{},
EndKey: []byte{},
Name: string(metaRegionName),
Server: serverNameToAddr(c.rootServerName),
}
}
func (c *client) getCachedLocation(table, row []byte) *RegionInfo {
c.mu.RLock()
defer c.mu.RUnlock()
tableStr := string(table)
if regions, ok := c.cachedRegionInfo[tableStr]; ok {
for _, region := range regions {
if (len(region.EndKey) == 0 ||
bytes.Compare(row, region.EndKey) < 0) &&
(len(region.StartKey) == 0 ||
bytes.Compare(row, region.StartKey) >= 0) {
return region
}
}
}
return nil
}
func (c *client) updateRegionCache(table []byte, region *RegionInfo) {
c.mu.Lock()
defer c.mu.Unlock()
tableStr := string(table)
if _, ok := c.cachedRegionInfo[tableStr]; !ok {
c.cachedRegionInfo[tableStr] = make(map[string]*RegionInfo)
}
c.cachedRegionInfo[tableStr][region.Name] = region
}
func (c *client) CleanRegionCache(table []byte) {
c.mu.Lock()
defer c.mu.Unlock()
delete(c.cachedRegionInfo, string(table))
}
func (c *client) CleanAllRegionCache() {
c.mu.Lock()
defer c.mu.Unlock()
c.cachedRegionInfo = map[string]map[string]*RegionInfo{}
}
func (c *client) LocateRegion(table, row []byte, useCache bool) (*RegionInfo, error) {
// If user wants to locate metaregion, just return it.
if bytes.Equal(table, metaTableName) {
return c.getMetaRegion(), nil
}
// Try to get location from cache.
if useCache {
if r := c.getCachedLocation(table, row); r != nil {
return r, nil
}
}
// If cache missed or not using cache, try to get and update region info.
metaRegion := c.getMetaRegion()
conn, err := c.getClientConn(metaRegion.Server)
if err != nil {
return nil, errors.Trace(err)
}
regionRow := c.createRegionName(table, row, beyondMaxTimestamp, true)
call := newCall(&proto.GetRequest{
Region: &proto.RegionSpecifier{
Type: proto.RegionSpecifier_REGION_NAME.Enum(),
Value: metaRegionName,
},
Get: &proto.Get{
Row: regionRow,
Column: []*proto.Column{&proto.Column{
Family: []byte("info"),
}},
ClosestRowBefore: pb.Bool(true),
},
})
err = conn.call(call)
if err != nil {
return nil, errors.Trace(err)
}
response := <-call.responseCh
switch r := response.(type) {
case *proto.GetResponse:
res := r.GetResult()
if res == nil {
return nil, errors.Errorf("Empty region: [table=%s] [row=%q] [region_row=%q]", table, row, regionRow)
}
rr := NewResultRow(res)
region, err := c.parseRegion(rr)
if err != nil {
return nil, errors.Trace(err)
}
c.updateRegionCache(table, region)
return region, nil
case *exception:
return nil, errors.New(r.msg)
default:
log.Warnf("Unknown response - %T - %v", r, r)
}
return nil, errors.Errorf("Couldn't find the region: [table=%s] [row=%q] [region_row=%q]", table, row, regionRow)
}
func (c *client) GetRegions(table []byte, useCache bool) ([]*RegionInfo, error) {
var regions []*RegionInfo
startKey := []byte("")
// Get first region.
region, err := c.LocateRegion(table, []byte(startKey), useCache)
if err != nil {
return nil, errors.Errorf("couldn't find any region: [table=%s] [useCache=%t]", table, useCache)
}
regions = append(regions, region)
startKey = region.EndKey
for len(startKey) > 0 {
region, err = c.LocateRegion(table, []byte(startKey), useCache)
if err != nil {
return nil, errors.Trace(err)
}
regions = append(regions, region)
startKey = region.EndKey
}
return regions, nil
}
func (c *client) Close() error {
if c.zkClient != nil {
c.zkClient.Close()
}
for _, conn := range c.cachedConns {
err := conn.close()
if err != nil {
return errors.Trace(err)
}
}
return nil
}

67
vendor/github.com/pingcap/go-hbase/client_ops.go generated vendored Normal file
View file

@ -0,0 +1,67 @@
package hbase
import (
"github.com/juju/errors"
"github.com/pingcap/go-hbase/proto"
)
func (c *client) Delete(table string, del *Delete) (bool, error) {
response, err := c.do([]byte(table), del.GetRow(), del, true)
if err != nil {
return false, errors.Trace(err)
}
switch r := response.(type) {
case *proto.MutateResponse:
return r.GetProcessed(), nil
}
return false, errors.Errorf("Invalid response seen [response: %#v]", response)
}
func (c *client) Get(table string, get *Get) (*ResultRow, error) {
response, err := c.do([]byte(table), get.GetRow(), get, true)
if err != nil {
return nil, errors.Trace(err)
}
switch r := response.(type) {
case *proto.GetResponse:
res := r.GetResult()
if res == nil {
return nil, errors.Errorf("Empty response: [table=%s] [row=%q]", table, get.GetRow())
}
return NewResultRow(res), nil
case *exception:
return nil, errors.New(r.msg)
}
return nil, errors.Errorf("Invalid response seen [response: %#v]", response)
}
func (c *client) Put(table string, put *Put) (bool, error) {
response, err := c.do([]byte(table), put.GetRow(), put, true)
if err != nil {
return false, errors.Trace(err)
}
switch r := response.(type) {
case *proto.MutateResponse:
return r.GetProcessed(), nil
}
return false, errors.Errorf("Invalid response seen [response: %#v]", response)
}
func (c *client) ServiceCall(table string, call *CoprocessorServiceCall) (*proto.CoprocessorServiceResponse, error) {
response, err := c.do([]byte(table), call.Row, call, true)
if err != nil {
return nil, errors.Trace(err)
}
switch r := response.(type) {
case *proto.CoprocessorServiceResponse:
return r, nil
case *exception:
return nil, errors.New(r.msg)
}
return nil, errors.Errorf("Invalid response seen [response: %#v]", response)
}

177
vendor/github.com/pingcap/go-hbase/column.go generated vendored Normal file
View file

@ -0,0 +1,177 @@
package hbase
import (
"bytes"
"fmt"
"io"
"github.com/juju/errors"
"github.com/pingcap/go-hbase/iohelper"
)
type Column struct {
Family []byte
Qual []byte
}
func NewColumn(family, qual []byte) *Column {
return &Column{
Family: family,
Qual: qual,
}
}
func encode(parts ...[]byte) ([]byte, error) {
buf := &bytes.Buffer{}
for _, p := range parts {
err := iohelper.WriteVarBytes(buf, p)
if err != nil {
return nil, errors.Trace(err)
}
}
return buf.Bytes(), nil
}
func decode(encoded []byte) ([][]byte, error) {
var ret [][]byte
buf := bytes.NewBuffer(encoded)
for {
b, err := iohelper.ReadVarBytes(buf)
if len(b) == 0 || (err != nil && ErrorEqual(err, io.EOF)) {
break
}
ret = append(ret, b)
}
return ret, nil
}
func (c *Column) Write(w io.Writer) error {
err := iohelper.WriteVarBytes(w, c.Family)
if err != nil {
return errors.Trace(err)
}
err = iohelper.WriteVarBytes(w, c.Qual)
if err != nil {
return errors.Trace(err)
}
return nil
}
func (c *Column) String() string {
b, err := encode(c.Family, c.Qual)
if err != nil {
return fmt.Sprintf("invalid column - %v", err)
}
return string(b)
}
func (c *Column) ParseFromString(s string) error {
pairs, err := decode([]byte(s))
if err != nil {
return errors.Trace(err)
}
c.Family = pairs[0]
c.Qual = pairs[1]
return nil
}
type ColumnCoordinate struct {
Table []byte
Row []byte
Column
}
func NewColumnCoordinate(table, row, family, qual []byte) *ColumnCoordinate {
return &ColumnCoordinate{
Table: table,
Row: row,
Column: Column{
Family: family,
Qual: qual,
},
}
}
func (c *ColumnCoordinate) Write(w io.Writer) error {
err := iohelper.WriteVarBytes(w, c.Table)
if err != nil {
return errors.Trace(err)
}
err = iohelper.WriteVarBytes(w, c.Row)
if err != nil {
return errors.Trace(err)
}
err = c.Column.Write(w)
if err != nil {
return errors.Trace(err)
}
return nil
}
func (c *ColumnCoordinate) Equal(a *ColumnCoordinate) bool {
return bytes.Compare(c.Table, a.Table) == 0 &&
bytes.Compare(c.Row, a.Row) == 0 &&
bytes.Compare(c.Family, a.Family) == 0 &&
bytes.Compare(c.Qual, a.Qual) == 0
}
func (c *ColumnCoordinate) String() string {
b, err := encode(c.Table, c.Row, c.Family, c.Qual)
if err != nil {
return fmt.Sprintf("invalid column coordinate - %v", err)
}
return string(b)
}
func (c *ColumnCoordinate) ParseFromString(s string) error {
pairs, err := decode([]byte(s))
if err != nil {
return errors.Trace(err)
}
c.Table = pairs[0]
c.Row = pairs[1]
c.Family = pairs[2]
c.Qual = pairs[3]
return nil
}
func (c *ColumnCoordinate) ParseField(b iohelper.ByteMultiReader) error {
table, err := iohelper.ReadVarBytes(b)
if err != nil {
return errors.Trace(err)
}
c.Table = table
row, err := iohelper.ReadVarBytes(b)
if err != nil {
return errors.Trace(err)
}
c.Row = row
family, err := iohelper.ReadVarBytes(b)
if err != nil {
return errors.Trace(err)
}
c.Family = family
qual, err := iohelper.ReadVarBytes(b)
if err != nil {
return errors.Trace(err)
}
c.Qual = qual
return nil
}
func (c *ColumnCoordinate) GetColumn() *Column {
return &Column{
Family: c.Family,
Qual: c.Qual,
}
}

291
vendor/github.com/pingcap/go-hbase/conn.go generated vendored Normal file
View file

@ -0,0 +1,291 @@
package hbase
import (
"bufio"
"bytes"
"io"
"net"
"strings"
"sync"
pb "github.com/golang/protobuf/proto"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase/iohelper"
"github.com/pingcap/go-hbase/proto"
)
type ServiceType byte
const (
MasterMonitorService = iota + 1
MasterService
MasterAdminService
AdminService
ClientService
RegionServerStatusService
)
// convert above const to protobuf string
var ServiceString = map[ServiceType]string{
MasterMonitorService: "MasterMonitorService",
MasterService: "MasterService",
MasterAdminService: "MasterAdminService",
AdminService: "AdminService",
ClientService: "ClientService",
RegionServerStatusService: "RegionServerStatusService",
}
type idGenerator struct {
n int
mu *sync.RWMutex
}
func newIdGenerator() *idGenerator {
return &idGenerator{
n: 0,
mu: &sync.RWMutex{},
}
}
func (a *idGenerator) get() int {
a.mu.RLock()
v := a.n
a.mu.RUnlock()
return v
}
func (a *idGenerator) incrAndGet() int {
a.mu.Lock()
a.n++
v := a.n
a.mu.Unlock()
return v
}
type connection struct {
mu sync.Mutex
addr string
conn net.Conn
bw *bufio.Writer
idGen *idGenerator
serviceType ServiceType
in chan *iohelper.PbBuffer
ongoingCalls map[int]*call
}
func processMessage(msg []byte) ([][]byte, error) {
buf := pb.NewBuffer(msg)
payloads := make([][]byte, 0)
// Question: why can we ignore this error?
for {
hbytes, err := buf.DecodeRawBytes(true)
if err != nil {
// Check whether error is `unexpected EOF`.
if strings.Contains(err.Error(), "unexpected EOF") {
break
}
log.Errorf("Decode raw bytes error - %v", errors.ErrorStack(err))
return nil, errors.Trace(err)
}
payloads = append(payloads, hbytes)
}
return payloads, nil
}
func readPayloads(r io.Reader) ([][]byte, error) {
nBytesExpecting, err := iohelper.ReadInt32(r)
if err != nil {
return nil, errors.Trace(err)
}
if nBytesExpecting > 0 {
buf, err := iohelper.ReadN(r, nBytesExpecting)
// Question: why should we return error only when we get an io.EOF error?
if err != nil && ErrorEqual(err, io.EOF) {
return nil, errors.Trace(err)
}
payloads, err := processMessage(buf)
if err != nil {
return nil, errors.Trace(err)
}
if len(payloads) > 0 {
return payloads, nil
}
}
return nil, errors.New("unexpected payload")
}
func newConnection(addr string, srvType ServiceType) (*connection, error) {
conn, err := net.Dial("tcp", addr)
if err != nil {
return nil, errors.Trace(err)
}
if _, ok := ServiceString[srvType]; !ok {
return nil, errors.Errorf("unexpected service type [serviceType=%d]", srvType)
}
c := &connection{
addr: addr,
bw: bufio.NewWriter(conn),
conn: conn,
in: make(chan *iohelper.PbBuffer, 20),
serviceType: srvType,
idGen: newIdGenerator(),
ongoingCalls: map[int]*call{},
}
err = c.init()
if err != nil {
return nil, errors.Trace(err)
}
return c, nil
}
func (c *connection) init() error {
err := c.writeHead()
if err != nil {
return errors.Trace(err)
}
err = c.writeConnectionHeader()
if err != nil {
return errors.Trace(err)
}
go func() {
err := c.processMessages()
if err != nil {
log.Warnf("process messages failed - %v", errors.ErrorStack(err))
return
}
}()
go c.dispatch()
return nil
}
func (c *connection) processMessages() error {
for {
msgs, err := readPayloads(c.conn)
if err != nil {
return errors.Trace(err)
}
var rh proto.ResponseHeader
err = pb.Unmarshal(msgs[0], &rh)
if err != nil {
return errors.Trace(err)
}
callId := rh.GetCallId()
c.mu.Lock()
call, ok := c.ongoingCalls[int(callId)]
if !ok {
c.mu.Unlock()
return errors.Errorf("Invalid call id: %d", callId)
}
delete(c.ongoingCalls, int(callId))
c.mu.Unlock()
exception := rh.GetException()
if exception != nil {
call.complete(errors.Errorf("Exception returned: %s\n%s", exception.GetExceptionClassName(), exception.GetStackTrace()), nil)
} else if len(msgs) == 2 {
call.complete(nil, msgs[1])
}
}
}
func (c *connection) writeHead() error {
buf := bytes.NewBuffer(nil)
buf.Write(hbaseHeaderBytes)
buf.WriteByte(0)
buf.WriteByte(80)
_, err := c.conn.Write(buf.Bytes())
return errors.Trace(err)
}
func (c *connection) writeConnectionHeader() error {
buf := iohelper.NewPbBuffer()
service := pb.String(ServiceString[c.serviceType])
err := buf.WritePBMessage(&proto.ConnectionHeader{
UserInfo: &proto.UserInformation{
EffectiveUser: pb.String("pingcap"),
},
ServiceName: service,
})
if err != nil {
return errors.Trace(err)
}
err = buf.PrependSize()
if err != nil {
return errors.Trace(err)
}
_, err = c.conn.Write(buf.Bytes())
if err != nil {
return errors.Trace(err)
}
return nil
}
func (c *connection) dispatch() {
for {
select {
case buf := <-c.in:
// TODO: add error check.
c.bw.Write(buf.Bytes())
if len(c.in) == 0 {
c.bw.Flush()
}
}
}
}
func (c *connection) call(request *call) error {
id := c.idGen.incrAndGet()
rh := &proto.RequestHeader{
CallId: pb.Uint32(uint32(id)),
MethodName: pb.String(request.methodName),
RequestParam: pb.Bool(true),
}
request.id = uint32(id)
bfrh := iohelper.NewPbBuffer()
err := bfrh.WritePBMessage(rh)
if err != nil {
return errors.Trace(err)
}
bfr := iohelper.NewPbBuffer()
err = bfr.WritePBMessage(request.request)
if err != nil {
return errors.Trace(err)
}
// Buf =>
// | total size | pb1 size | pb1 | pb2 size | pb2 | ...
buf := iohelper.NewPbBuffer()
buf.WriteDelimitedBuffers(bfrh, bfr)
c.mu.Lock()
c.ongoingCalls[id] = request
c.in <- buf
c.mu.Unlock()
return nil
}
func (c *connection) close() error {
return c.conn.Close()
}

113
vendor/github.com/pingcap/go-hbase/del.go generated vendored Normal file
View file

@ -0,0 +1,113 @@
package hbase
import (
pb "github.com/golang/protobuf/proto"
"github.com/pingcap/go-hbase/proto"
"fmt"
"math"
"strings"
)
type Delete struct {
Row []byte
Families set
FamilyQuals map[string]set
Ts map[string]uint64
}
func NewDelete(row []byte) *Delete {
return &Delete{
Row: row,
Families: newSet(),
FamilyQuals: make(map[string]set),
Ts: make(map[string]uint64),
}
}
func (d *Delete) AddString(famqual string) error {
parts := strings.Split(famqual, ":")
if len(parts) > 2 {
return fmt.Errorf("Too many colons were found in the family:qualifier string. '%s'", famqual)
} else if len(parts) == 2 {
d.AddStringColumn(parts[0], parts[1])
} else {
d.AddStringFamily(famqual)
}
return nil
}
func (d *Delete) GetRow() []byte {
return d.Row
}
func (d *Delete) AddColumn(family, qual []byte) *Delete {
d.AddFamily(family)
d.FamilyQuals[string(family)].add(string(qual))
return d
}
func (d *Delete) AddStringColumn(family, qual string) *Delete {
return d.AddColumn([]byte(family), []byte(qual))
}
func (d *Delete) AddFamily(family []byte) *Delete {
d.Families.add(string(family))
if _, ok := d.FamilyQuals[string(family)]; !ok {
d.FamilyQuals[string(family)] = newSet()
}
return d
}
func (d *Delete) AddStringFamily(family string) *Delete {
return d.AddFamily([]byte(family))
}
func (d *Delete) AddColumnWithTimestamp(family, qual []byte, ts uint64) *Delete {
d.AddColumn(family, qual)
k := string(family) + ":" + string(qual)
d.Ts[k] = ts
return d
}
func (d *Delete) ToProto() pb.Message {
del := &proto.MutationProto{
Row: d.Row,
MutateType: proto.MutationProto_DELETE.Enum(),
}
for family := range d.Families {
cv := &proto.MutationProto_ColumnValue{
Family: []byte(family),
QualifierValue: make([]*proto.MutationProto_ColumnValue_QualifierValue, 0),
}
if len(d.FamilyQuals[family]) == 0 {
cv.QualifierValue = append(cv.QualifierValue, &proto.MutationProto_ColumnValue_QualifierValue{
Qualifier: nil,
Timestamp: pb.Uint64(uint64(math.MaxInt64)),
DeleteType: proto.MutationProto_DELETE_FAMILY.Enum(),
})
}
for qual := range d.FamilyQuals[family] {
v := &proto.MutationProto_ColumnValue_QualifierValue{
Qualifier: []byte(qual),
Timestamp: pb.Uint64(uint64(math.MaxInt64)),
DeleteType: proto.MutationProto_DELETE_MULTIPLE_VERSIONS.Enum(),
}
tsKey := string(family) + ":" + string(qual)
if ts, ok := d.Ts[tsKey]; ok {
v.Timestamp = pb.Uint64(ts)
v.DeleteType = proto.MutationProto_DELETE_ONE_VERSION.Enum()
}
cv.QualifierValue = append(cv.QualifierValue, v)
}
del.ColumnValue = append(del.ColumnValue, cv)
}
return del
}

105
vendor/github.com/pingcap/go-hbase/get.go generated vendored Normal file
View file

@ -0,0 +1,105 @@
package hbase
import (
"strings"
pb "github.com/golang/protobuf/proto"
"github.com/juju/errors"
"github.com/pingcap/go-hbase/proto"
)
type Get struct {
Row []byte
Families set
FamilyQuals map[string]set
Versions int32
TsRangeFrom uint64
TsRangeTo uint64
}
func NewGet(row []byte) *Get {
return &Get{
Row: append([]byte(nil), row...),
Families: newSet(),
FamilyQuals: make(map[string]set),
Versions: 1,
}
}
func (g *Get) GetRow() []byte {
return g.Row
}
func (g *Get) AddString(famqual string) error {
parts := strings.Split(famqual, ":")
if len(parts) > 2 {
return errors.Errorf("Too many colons were found in the family:qualifier string. '%s'", famqual)
} else if len(parts) == 2 {
g.AddStringColumn(parts[0], parts[1])
} else {
g.AddStringFamily(famqual)
}
return nil
}
func (g *Get) AddColumn(family, qual []byte) *Get {
g.AddFamily(family)
g.FamilyQuals[string(family)].add(string(qual))
return g
}
func (g *Get) AddStringColumn(family, qual string) *Get {
return g.AddColumn([]byte(family), []byte(qual))
}
func (g *Get) AddFamily(family []byte) *Get {
g.Families.add(string(family))
if _, ok := g.FamilyQuals[string(family)]; !ok {
g.FamilyQuals[string(family)] = newSet()
}
return g
}
func (g *Get) AddStringFamily(family string) *Get {
return g.AddFamily([]byte(family))
}
func (g *Get) AddTimeRange(from uint64, to uint64) *Get {
g.TsRangeFrom = from
g.TsRangeTo = to
return g
}
func (g *Get) SetMaxVersion(maxVersion int32) *Get {
g.Versions = maxVersion
return g
}
func (g *Get) ToProto() pb.Message {
get := &proto.Get{
Row: g.Row,
}
if g.TsRangeFrom != 0 && g.TsRangeTo != 0 && g.TsRangeFrom <= g.TsRangeTo {
get.TimeRange = &proto.TimeRange{
From: pb.Uint64(g.TsRangeFrom),
To: pb.Uint64(g.TsRangeTo),
}
}
for v := range g.Families {
col := &proto.Column{
Family: []byte(v),
}
var quals [][]byte
for qual := range g.FamilyQuals[v] {
quals = append(quals, []byte(qual))
}
col.Qualifier = quals
get.Column = append(get.Column, col)
}
get.MaxVersions = pb.Uint32(uint32(g.Versions))
return get
}

View file

@ -0,0 +1,8 @@
package iohelper
import "io"
type ByteMultiReader interface {
io.ByteReader
io.Reader
}

111
vendor/github.com/pingcap/go-hbase/iohelper/pbbuffer.go generated vendored Normal file
View file

@ -0,0 +1,111 @@
package iohelper
import (
"encoding/binary"
pb "github.com/golang/protobuf/proto"
"github.com/juju/errors"
)
type PbBuffer struct {
b []byte
}
func NewPbBuffer() *PbBuffer {
b := []byte{}
return &PbBuffer{
b: b,
}
}
func (b *PbBuffer) Bytes() []byte {
return b.b
}
func (b *PbBuffer) Write(d []byte) (int, error) {
b.b = append(b.b, d...)
return len(d), nil
}
func (b *PbBuffer) WriteByte(d byte) error {
return binary.Write(b, binary.BigEndian, d)
}
func (b *PbBuffer) WriteString(d string) error {
return binary.Write(b, binary.BigEndian, d)
}
func (b *PbBuffer) WriteInt32(d int32) error {
return binary.Write(b, binary.BigEndian, d)
}
func (b *PbBuffer) WriteInt64(d int64) error {
return binary.Write(b, binary.BigEndian, d)
}
func (b *PbBuffer) WriteFloat32(d float32) error {
return binary.Write(b, binary.BigEndian, d)
}
func (b *PbBuffer) WriteFloat64(d float64) error {
return binary.Write(b, binary.BigEndian, d)
}
func (b *PbBuffer) WritePBMessage(d pb.Message) error {
buf, err := pb.Marshal(d)
if err != nil {
return errors.Trace(err)
}
_, err = b.Write(buf)
return errors.Trace(err)
}
func (b *PbBuffer) WriteDelimitedBuffers(bufs ...*PbBuffer) error {
totalLength := 0
lens := make([][]byte, len(bufs))
for i, v := range bufs {
n := len(v.Bytes())
lenb := pb.EncodeVarint(uint64(n))
totalLength += len(lenb) + n
lens[i] = lenb
}
err := b.WriteInt32(int32(totalLength))
if err != nil {
return errors.Trace(err)
}
for i, v := range bufs {
_, err = b.Write(lens[i])
if err != nil {
return errors.Trace(err)
}
_, err = b.Write(v.Bytes())
if err != nil {
return errors.Trace(err)
}
}
return nil
}
func (b *PbBuffer) PrependSize() error {
size := int32(len(b.b))
newBuf := NewPbBuffer()
err := newBuf.WriteInt32(size)
if err != nil {
return errors.Trace(err)
}
_, err = newBuf.Write(b.b)
if err != nil {
return errors.Trace(err)
}
*b = *newBuf
return nil
}

177
vendor/github.com/pingcap/go-hbase/iohelper/utils.go generated vendored Normal file
View file

@ -0,0 +1,177 @@
package iohelper
import (
"bytes"
"encoding/binary"
"io"
"github.com/juju/errors"
)
var (
cachedItob [][]byte
)
func init() {
cachedItob = make([][]byte, 1024)
for i := 0; i < len(cachedItob); i++ {
var b bytes.Buffer
writeVLong(&b, int64(i))
cachedItob[i] = b.Bytes()
}
}
func itob(i int) ([]byte, error) {
if i >= 0 && i < len(cachedItob) {
return cachedItob[i], nil
}
var b bytes.Buffer
err := binary.Write(&b, binary.BigEndian, i)
if err != nil {
return nil, errors.Trace(err)
}
return b.Bytes(), nil
}
func decodeVIntSize(value byte) int32 {
if int32(value) >= -112 {
return int32(1)
}
if int32(value) < -120 {
return -119 - int32(value)
}
return -111 - int32(value)
}
func isNegativeVInt(value byte) bool {
return int32(value) < -120 || int32(value) >= -112 && int32(value) < 0
}
func readVLong(r io.Reader) (int64, error) {
var firstByte byte
err := binary.Read(r, binary.BigEndian, &firstByte)
if err != nil {
return 0, errors.Trace(err)
}
l := decodeVIntSize(firstByte)
if l == 1 {
return int64(firstByte), nil
}
var (
i int64
idx int32
)
for idx = 0; idx < l-1; idx++ {
var b byte
err = binary.Read(r, binary.BigEndian, &b)
if err != nil {
return 0, errors.Trace(err)
}
i <<= 8
i |= int64(b & 255)
}
if isNegativeVInt(firstByte) {
return ^i, nil
}
return i, nil
}
func writeVLong(w io.Writer, i int64) error {
var err error
if i >= -112 && i <= 127 {
err = binary.Write(w, binary.BigEndian, byte(i))
if err != nil {
return errors.Trace(err)
}
} else {
var l int32 = -112
if i < 0 {
i = ^i
l = -120
}
var tmp int64
for tmp = i; tmp != 0; l-- {
tmp >>= 8
}
err = binary.Write(w, binary.BigEndian, byte(l))
if err != nil {
return errors.Trace(err)
}
if l < -120 {
l = -(l + 120)
} else {
l = -(l + 112)
}
for idx := l; idx != 0; idx-- {
var mask int64
shiftbits := uint((idx - 1) * 8)
mask = int64(255) << shiftbits
err = binary.Write(w, binary.BigEndian, byte((i&mask)>>shiftbits))
if err != nil {
return errors.Trace(err)
}
}
}
return nil
}
func ReadVarBytes(r ByteMultiReader) ([]byte, error) {
sz, err := readVLong(r)
if err != nil {
return nil, errors.Trace(err)
}
b := make([]byte, sz)
_, err = r.Read(b)
if err != nil {
return nil, errors.Trace(err)
}
return b, nil
}
func WriteVarBytes(w io.Writer, b []byte) error {
lenb, err := itob(len(b))
if err != nil {
return errors.Trace(err)
}
_, err = w.Write(lenb)
if err != nil {
return errors.Trace(err)
}
_, err = w.Write(b)
return errors.Trace(err)
}
func ReadInt32(r io.Reader) (int32, error) {
var n int32
err := binary.Read(r, binary.BigEndian, &n)
return n, errors.Trace(err)
}
func ReadN(r io.Reader, n int32) ([]byte, error) {
b := make([]byte, n)
_, err := io.ReadFull(r, b)
return b, errors.Trace(err)
}
func ReadUint64(r io.Reader) (uint64, error) {
var n uint64
err := binary.Read(r, binary.BigEndian, &n)
return n, errors.Trace(err)
}

View file

@ -0,0 +1,451 @@
// Code generated by protoc-gen-go.
// source: AccessControl.proto
// DO NOT EDIT!
/*
Package proto is a generated protocol buffer package.
It is generated from these files:
AccessControl.proto
Admin.proto
Aggregate.proto
Authentication.proto
Cell.proto
Client.proto
ClusterId.proto
ClusterStatus.proto
Comparator.proto
Encryption.proto
ErrorHandling.proto
FS.proto
Filter.proto
HBase.proto
HFile.proto
LoadBalancer.proto
MapReduce.proto
Master.proto
MultiRowMutation.proto
RPC.proto
RegionServerStatus.proto
RowProcessor.proto
SecureBulkLoad.proto
Snapshot.proto
Themis.proto
Tracing.proto
VisibilityLabels.proto
WAL.proto
ZooKeeper.proto
It has these top-level messages:
Permission
TablePermission
NamespacePermission
GlobalPermission
UserPermission
UsersAndPermissions
GrantRequest
GrantResponse
RevokeRequest
RevokeResponse
GetUserPermissionsRequest
GetUserPermissionsResponse
CheckPermissionsRequest
CheckPermissionsResponse
*/
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type Permission_Action int32
const (
Permission_READ Permission_Action = 0
Permission_WRITE Permission_Action = 1
Permission_EXEC Permission_Action = 2
Permission_CREATE Permission_Action = 3
Permission_ADMIN Permission_Action = 4
)
var Permission_Action_name = map[int32]string{
0: "READ",
1: "WRITE",
2: "EXEC",
3: "CREATE",
4: "ADMIN",
}
var Permission_Action_value = map[string]int32{
"READ": 0,
"WRITE": 1,
"EXEC": 2,
"CREATE": 3,
"ADMIN": 4,
}
func (x Permission_Action) Enum() *Permission_Action {
p := new(Permission_Action)
*p = x
return p
}
func (x Permission_Action) String() string {
return proto1.EnumName(Permission_Action_name, int32(x))
}
func (x *Permission_Action) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(Permission_Action_value, data, "Permission_Action")
if err != nil {
return err
}
*x = Permission_Action(value)
return nil
}
type Permission_Type int32
const (
Permission_Global Permission_Type = 1
Permission_Namespace Permission_Type = 2
Permission_Table Permission_Type = 3
)
var Permission_Type_name = map[int32]string{
1: "Global",
2: "Namespace",
3: "Table",
}
var Permission_Type_value = map[string]int32{
"Global": 1,
"Namespace": 2,
"Table": 3,
}
func (x Permission_Type) Enum() *Permission_Type {
p := new(Permission_Type)
*p = x
return p
}
func (x Permission_Type) String() string {
return proto1.EnumName(Permission_Type_name, int32(x))
}
func (x *Permission_Type) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(Permission_Type_value, data, "Permission_Type")
if err != nil {
return err
}
*x = Permission_Type(value)
return nil
}
type Permission struct {
Type *Permission_Type `protobuf:"varint,1,req,name=type,enum=proto.Permission_Type" json:"type,omitempty"`
GlobalPermission *GlobalPermission `protobuf:"bytes,2,opt,name=global_permission" json:"global_permission,omitempty"`
NamespacePermission *NamespacePermission `protobuf:"bytes,3,opt,name=namespace_permission" json:"namespace_permission,omitempty"`
TablePermission *TablePermission `protobuf:"bytes,4,opt,name=table_permission" json:"table_permission,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Permission) Reset() { *m = Permission{} }
func (m *Permission) String() string { return proto1.CompactTextString(m) }
func (*Permission) ProtoMessage() {}
func (m *Permission) GetType() Permission_Type {
if m != nil && m.Type != nil {
return *m.Type
}
return Permission_Global
}
func (m *Permission) GetGlobalPermission() *GlobalPermission {
if m != nil {
return m.GlobalPermission
}
return nil
}
func (m *Permission) GetNamespacePermission() *NamespacePermission {
if m != nil {
return m.NamespacePermission
}
return nil
}
func (m *Permission) GetTablePermission() *TablePermission {
if m != nil {
return m.TablePermission
}
return nil
}
type TablePermission struct {
TableName *TableName `protobuf:"bytes,1,opt,name=table_name" json:"table_name,omitempty"`
Family []byte `protobuf:"bytes,2,opt,name=family" json:"family,omitempty"`
Qualifier []byte `protobuf:"bytes,3,opt,name=qualifier" json:"qualifier,omitempty"`
Action []Permission_Action `protobuf:"varint,4,rep,name=action,enum=proto.Permission_Action" json:"action,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *TablePermission) Reset() { *m = TablePermission{} }
func (m *TablePermission) String() string { return proto1.CompactTextString(m) }
func (*TablePermission) ProtoMessage() {}
func (m *TablePermission) GetTableName() *TableName {
if m != nil {
return m.TableName
}
return nil
}
func (m *TablePermission) GetFamily() []byte {
if m != nil {
return m.Family
}
return nil
}
func (m *TablePermission) GetQualifier() []byte {
if m != nil {
return m.Qualifier
}
return nil
}
func (m *TablePermission) GetAction() []Permission_Action {
if m != nil {
return m.Action
}
return nil
}
type NamespacePermission struct {
NamespaceName []byte `protobuf:"bytes,1,opt,name=namespace_name" json:"namespace_name,omitempty"`
Action []Permission_Action `protobuf:"varint,2,rep,name=action,enum=proto.Permission_Action" json:"action,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *NamespacePermission) Reset() { *m = NamespacePermission{} }
func (m *NamespacePermission) String() string { return proto1.CompactTextString(m) }
func (*NamespacePermission) ProtoMessage() {}
func (m *NamespacePermission) GetNamespaceName() []byte {
if m != nil {
return m.NamespaceName
}
return nil
}
func (m *NamespacePermission) GetAction() []Permission_Action {
if m != nil {
return m.Action
}
return nil
}
type GlobalPermission struct {
Action []Permission_Action `protobuf:"varint,1,rep,name=action,enum=proto.Permission_Action" json:"action,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GlobalPermission) Reset() { *m = GlobalPermission{} }
func (m *GlobalPermission) String() string { return proto1.CompactTextString(m) }
func (*GlobalPermission) ProtoMessage() {}
func (m *GlobalPermission) GetAction() []Permission_Action {
if m != nil {
return m.Action
}
return nil
}
type UserPermission struct {
User []byte `protobuf:"bytes,1,req,name=user" json:"user,omitempty"`
Permission *Permission `protobuf:"bytes,3,req,name=permission" json:"permission,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *UserPermission) Reset() { *m = UserPermission{} }
func (m *UserPermission) String() string { return proto1.CompactTextString(m) }
func (*UserPermission) ProtoMessage() {}
func (m *UserPermission) GetUser() []byte {
if m != nil {
return m.User
}
return nil
}
func (m *UserPermission) GetPermission() *Permission {
if m != nil {
return m.Permission
}
return nil
}
// *
// Content of the /hbase/acl/<table or namespace> znode.
type UsersAndPermissions struct {
UserPermissions []*UsersAndPermissions_UserPermissions `protobuf:"bytes,1,rep,name=user_permissions" json:"user_permissions,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *UsersAndPermissions) Reset() { *m = UsersAndPermissions{} }
func (m *UsersAndPermissions) String() string { return proto1.CompactTextString(m) }
func (*UsersAndPermissions) ProtoMessage() {}
func (m *UsersAndPermissions) GetUserPermissions() []*UsersAndPermissions_UserPermissions {
if m != nil {
return m.UserPermissions
}
return nil
}
type UsersAndPermissions_UserPermissions struct {
User []byte `protobuf:"bytes,1,req,name=user" json:"user,omitempty"`
Permissions []*Permission `protobuf:"bytes,2,rep,name=permissions" json:"permissions,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *UsersAndPermissions_UserPermissions) Reset() { *m = UsersAndPermissions_UserPermissions{} }
func (m *UsersAndPermissions_UserPermissions) String() string { return proto1.CompactTextString(m) }
func (*UsersAndPermissions_UserPermissions) ProtoMessage() {}
func (m *UsersAndPermissions_UserPermissions) GetUser() []byte {
if m != nil {
return m.User
}
return nil
}
func (m *UsersAndPermissions_UserPermissions) GetPermissions() []*Permission {
if m != nil {
return m.Permissions
}
return nil
}
type GrantRequest struct {
UserPermission *UserPermission `protobuf:"bytes,1,req,name=user_permission" json:"user_permission,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GrantRequest) Reset() { *m = GrantRequest{} }
func (m *GrantRequest) String() string { return proto1.CompactTextString(m) }
func (*GrantRequest) ProtoMessage() {}
func (m *GrantRequest) GetUserPermission() *UserPermission {
if m != nil {
return m.UserPermission
}
return nil
}
type GrantResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *GrantResponse) Reset() { *m = GrantResponse{} }
func (m *GrantResponse) String() string { return proto1.CompactTextString(m) }
func (*GrantResponse) ProtoMessage() {}
type RevokeRequest struct {
UserPermission *UserPermission `protobuf:"bytes,1,req,name=user_permission" json:"user_permission,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RevokeRequest) Reset() { *m = RevokeRequest{} }
func (m *RevokeRequest) String() string { return proto1.CompactTextString(m) }
func (*RevokeRequest) ProtoMessage() {}
func (m *RevokeRequest) GetUserPermission() *UserPermission {
if m != nil {
return m.UserPermission
}
return nil
}
type RevokeResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *RevokeResponse) Reset() { *m = RevokeResponse{} }
func (m *RevokeResponse) String() string { return proto1.CompactTextString(m) }
func (*RevokeResponse) ProtoMessage() {}
type GetUserPermissionsRequest struct {
Type *Permission_Type `protobuf:"varint,1,opt,name=type,enum=proto.Permission_Type" json:"type,omitempty"`
TableName *TableName `protobuf:"bytes,2,opt,name=table_name" json:"table_name,omitempty"`
NamespaceName []byte `protobuf:"bytes,3,opt,name=namespace_name" json:"namespace_name,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetUserPermissionsRequest) Reset() { *m = GetUserPermissionsRequest{} }
func (m *GetUserPermissionsRequest) String() string { return proto1.CompactTextString(m) }
func (*GetUserPermissionsRequest) ProtoMessage() {}
func (m *GetUserPermissionsRequest) GetType() Permission_Type {
if m != nil && m.Type != nil {
return *m.Type
}
return Permission_Global
}
func (m *GetUserPermissionsRequest) GetTableName() *TableName {
if m != nil {
return m.TableName
}
return nil
}
func (m *GetUserPermissionsRequest) GetNamespaceName() []byte {
if m != nil {
return m.NamespaceName
}
return nil
}
type GetUserPermissionsResponse struct {
UserPermission []*UserPermission `protobuf:"bytes,1,rep,name=user_permission" json:"user_permission,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetUserPermissionsResponse) Reset() { *m = GetUserPermissionsResponse{} }
func (m *GetUserPermissionsResponse) String() string { return proto1.CompactTextString(m) }
func (*GetUserPermissionsResponse) ProtoMessage() {}
func (m *GetUserPermissionsResponse) GetUserPermission() []*UserPermission {
if m != nil {
return m.UserPermission
}
return nil
}
type CheckPermissionsRequest struct {
Permission []*Permission `protobuf:"bytes,1,rep,name=permission" json:"permission,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CheckPermissionsRequest) Reset() { *m = CheckPermissionsRequest{} }
func (m *CheckPermissionsRequest) String() string { return proto1.CompactTextString(m) }
func (*CheckPermissionsRequest) ProtoMessage() {}
func (m *CheckPermissionsRequest) GetPermission() []*Permission {
if m != nil {
return m.Permission
}
return nil
}
type CheckPermissionsResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *CheckPermissionsResponse) Reset() { *m = CheckPermissionsResponse{} }
func (m *CheckPermissionsResponse) String() string { return proto1.CompactTextString(m) }
func (*CheckPermissionsResponse) ProtoMessage() {}
func init() {
proto1.RegisterEnum("proto.Permission_Action", Permission_Action_name, Permission_Action_value)
proto1.RegisterEnum("proto.Permission_Type", Permission_Type_name, Permission_Type_value)
}

769
vendor/github.com/pingcap/go-hbase/proto/Admin.pb.go generated vendored Normal file
View file

@ -0,0 +1,769 @@
// Code generated by protoc-gen-go.
// source: Admin.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type GetRegionInfoResponse_CompactionState int32
const (
GetRegionInfoResponse_NONE GetRegionInfoResponse_CompactionState = 0
GetRegionInfoResponse_MINOR GetRegionInfoResponse_CompactionState = 1
GetRegionInfoResponse_MAJOR GetRegionInfoResponse_CompactionState = 2
GetRegionInfoResponse_MAJOR_AND_MINOR GetRegionInfoResponse_CompactionState = 3
)
var GetRegionInfoResponse_CompactionState_name = map[int32]string{
0: "NONE",
1: "MINOR",
2: "MAJOR",
3: "MAJOR_AND_MINOR",
}
var GetRegionInfoResponse_CompactionState_value = map[string]int32{
"NONE": 0,
"MINOR": 1,
"MAJOR": 2,
"MAJOR_AND_MINOR": 3,
}
func (x GetRegionInfoResponse_CompactionState) Enum() *GetRegionInfoResponse_CompactionState {
p := new(GetRegionInfoResponse_CompactionState)
*p = x
return p
}
func (x GetRegionInfoResponse_CompactionState) String() string {
return proto1.EnumName(GetRegionInfoResponse_CompactionState_name, int32(x))
}
func (x *GetRegionInfoResponse_CompactionState) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(GetRegionInfoResponse_CompactionState_value, data, "GetRegionInfoResponse_CompactionState")
if err != nil {
return err
}
*x = GetRegionInfoResponse_CompactionState(value)
return nil
}
type OpenRegionResponse_RegionOpeningState int32
const (
OpenRegionResponse_OPENED OpenRegionResponse_RegionOpeningState = 0
OpenRegionResponse_ALREADY_OPENED OpenRegionResponse_RegionOpeningState = 1
OpenRegionResponse_FAILED_OPENING OpenRegionResponse_RegionOpeningState = 2
)
var OpenRegionResponse_RegionOpeningState_name = map[int32]string{
0: "OPENED",
1: "ALREADY_OPENED",
2: "FAILED_OPENING",
}
var OpenRegionResponse_RegionOpeningState_value = map[string]int32{
"OPENED": 0,
"ALREADY_OPENED": 1,
"FAILED_OPENING": 2,
}
func (x OpenRegionResponse_RegionOpeningState) Enum() *OpenRegionResponse_RegionOpeningState {
p := new(OpenRegionResponse_RegionOpeningState)
*p = x
return p
}
func (x OpenRegionResponse_RegionOpeningState) String() string {
return proto1.EnumName(OpenRegionResponse_RegionOpeningState_name, int32(x))
}
func (x *OpenRegionResponse_RegionOpeningState) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(OpenRegionResponse_RegionOpeningState_value, data, "OpenRegionResponse_RegionOpeningState")
if err != nil {
return err
}
*x = OpenRegionResponse_RegionOpeningState(value)
return nil
}
type GetRegionInfoRequest struct {
Region *RegionSpecifier `protobuf:"bytes,1,req,name=region" json:"region,omitempty"`
CompactionState *bool `protobuf:"varint,2,opt,name=compaction_state" json:"compaction_state,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetRegionInfoRequest) Reset() { *m = GetRegionInfoRequest{} }
func (m *GetRegionInfoRequest) String() string { return proto1.CompactTextString(m) }
func (*GetRegionInfoRequest) ProtoMessage() {}
func (m *GetRegionInfoRequest) GetRegion() *RegionSpecifier {
if m != nil {
return m.Region
}
return nil
}
func (m *GetRegionInfoRequest) GetCompactionState() bool {
if m != nil && m.CompactionState != nil {
return *m.CompactionState
}
return false
}
type GetRegionInfoResponse struct {
RegionInfo *RegionInfo `protobuf:"bytes,1,req,name=region_info" json:"region_info,omitempty"`
CompactionState *GetRegionInfoResponse_CompactionState `protobuf:"varint,2,opt,name=compaction_state,enum=proto.GetRegionInfoResponse_CompactionState" json:"compaction_state,omitempty"`
IsRecovering *bool `protobuf:"varint,3,opt,name=isRecovering" json:"isRecovering,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetRegionInfoResponse) Reset() { *m = GetRegionInfoResponse{} }
func (m *GetRegionInfoResponse) String() string { return proto1.CompactTextString(m) }
func (*GetRegionInfoResponse) ProtoMessage() {}
func (m *GetRegionInfoResponse) GetRegionInfo() *RegionInfo {
if m != nil {
return m.RegionInfo
}
return nil
}
func (m *GetRegionInfoResponse) GetCompactionState() GetRegionInfoResponse_CompactionState {
if m != nil && m.CompactionState != nil {
return *m.CompactionState
}
return GetRegionInfoResponse_NONE
}
func (m *GetRegionInfoResponse) GetIsRecovering() bool {
if m != nil && m.IsRecovering != nil {
return *m.IsRecovering
}
return false
}
// *
// Get a list of store files for a set of column families in a particular region.
// If no column family is specified, get the store files for all column families.
type GetStoreFileRequest struct {
Region *RegionSpecifier `protobuf:"bytes,1,req,name=region" json:"region,omitempty"`
Family [][]byte `protobuf:"bytes,2,rep,name=family" json:"family,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetStoreFileRequest) Reset() { *m = GetStoreFileRequest{} }
func (m *GetStoreFileRequest) String() string { return proto1.CompactTextString(m) }
func (*GetStoreFileRequest) ProtoMessage() {}
func (m *GetStoreFileRequest) GetRegion() *RegionSpecifier {
if m != nil {
return m.Region
}
return nil
}
func (m *GetStoreFileRequest) GetFamily() [][]byte {
if m != nil {
return m.Family
}
return nil
}
type GetStoreFileResponse struct {
StoreFile []string `protobuf:"bytes,1,rep,name=store_file" json:"store_file,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetStoreFileResponse) Reset() { *m = GetStoreFileResponse{} }
func (m *GetStoreFileResponse) String() string { return proto1.CompactTextString(m) }
func (*GetStoreFileResponse) ProtoMessage() {}
func (m *GetStoreFileResponse) GetStoreFile() []string {
if m != nil {
return m.StoreFile
}
return nil
}
type GetOnlineRegionRequest struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *GetOnlineRegionRequest) Reset() { *m = GetOnlineRegionRequest{} }
func (m *GetOnlineRegionRequest) String() string { return proto1.CompactTextString(m) }
func (*GetOnlineRegionRequest) ProtoMessage() {}
type GetOnlineRegionResponse struct {
RegionInfo []*RegionInfo `protobuf:"bytes,1,rep,name=region_info" json:"region_info,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetOnlineRegionResponse) Reset() { *m = GetOnlineRegionResponse{} }
func (m *GetOnlineRegionResponse) String() string { return proto1.CompactTextString(m) }
func (*GetOnlineRegionResponse) ProtoMessage() {}
func (m *GetOnlineRegionResponse) GetRegionInfo() []*RegionInfo {
if m != nil {
return m.RegionInfo
}
return nil
}
type OpenRegionRequest struct {
OpenInfo []*OpenRegionRequest_RegionOpenInfo `protobuf:"bytes,1,rep,name=open_info" json:"open_info,omitempty"`
// the intended server for this RPC.
ServerStartCode *uint64 `protobuf:"varint,2,opt,name=serverStartCode" json:"serverStartCode,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *OpenRegionRequest) Reset() { *m = OpenRegionRequest{} }
func (m *OpenRegionRequest) String() string { return proto1.CompactTextString(m) }
func (*OpenRegionRequest) ProtoMessage() {}
func (m *OpenRegionRequest) GetOpenInfo() []*OpenRegionRequest_RegionOpenInfo {
if m != nil {
return m.OpenInfo
}
return nil
}
func (m *OpenRegionRequest) GetServerStartCode() uint64 {
if m != nil && m.ServerStartCode != nil {
return *m.ServerStartCode
}
return 0
}
type OpenRegionRequest_RegionOpenInfo struct {
Region *RegionInfo `protobuf:"bytes,1,req,name=region" json:"region,omitempty"`
VersionOfOfflineNode *uint32 `protobuf:"varint,2,opt,name=version_of_offline_node" json:"version_of_offline_node,omitempty"`
FavoredNodes []*ServerName `protobuf:"bytes,3,rep,name=favored_nodes" json:"favored_nodes,omitempty"`
// open region for distributedLogReplay
OpenForDistributedLogReplay *bool `protobuf:"varint,4,opt,name=openForDistributedLogReplay" json:"openForDistributedLogReplay,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *OpenRegionRequest_RegionOpenInfo) Reset() { *m = OpenRegionRequest_RegionOpenInfo{} }
func (m *OpenRegionRequest_RegionOpenInfo) String() string { return proto1.CompactTextString(m) }
func (*OpenRegionRequest_RegionOpenInfo) ProtoMessage() {}
func (m *OpenRegionRequest_RegionOpenInfo) GetRegion() *RegionInfo {
if m != nil {
return m.Region
}
return nil
}
func (m *OpenRegionRequest_RegionOpenInfo) GetVersionOfOfflineNode() uint32 {
if m != nil && m.VersionOfOfflineNode != nil {
return *m.VersionOfOfflineNode
}
return 0
}
func (m *OpenRegionRequest_RegionOpenInfo) GetFavoredNodes() []*ServerName {
if m != nil {
return m.FavoredNodes
}
return nil
}
func (m *OpenRegionRequest_RegionOpenInfo) GetOpenForDistributedLogReplay() bool {
if m != nil && m.OpenForDistributedLogReplay != nil {
return *m.OpenForDistributedLogReplay
}
return false
}
type OpenRegionResponse struct {
OpeningState []OpenRegionResponse_RegionOpeningState `protobuf:"varint,1,rep,name=opening_state,enum=proto.OpenRegionResponse_RegionOpeningState" json:"opening_state,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *OpenRegionResponse) Reset() { *m = OpenRegionResponse{} }
func (m *OpenRegionResponse) String() string { return proto1.CompactTextString(m) }
func (*OpenRegionResponse) ProtoMessage() {}
func (m *OpenRegionResponse) GetOpeningState() []OpenRegionResponse_RegionOpeningState {
if m != nil {
return m.OpeningState
}
return nil
}
// *
// Closes the specified region and will use or not use ZK during the close
// according to the specified flag.
type CloseRegionRequest struct {
Region *RegionSpecifier `protobuf:"bytes,1,req,name=region" json:"region,omitempty"`
VersionOfClosingNode *uint32 `protobuf:"varint,2,opt,name=version_of_closing_node" json:"version_of_closing_node,omitempty"`
TransitionIn_ZK *bool `protobuf:"varint,3,opt,name=transition_in_ZK,def=1" json:"transition_in_ZK,omitempty"`
DestinationServer *ServerName `protobuf:"bytes,4,opt,name=destination_server" json:"destination_server,omitempty"`
// the intended server for this RPC.
ServerStartCode *uint64 `protobuf:"varint,5,opt,name=serverStartCode" json:"serverStartCode,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CloseRegionRequest) Reset() { *m = CloseRegionRequest{} }
func (m *CloseRegionRequest) String() string { return proto1.CompactTextString(m) }
func (*CloseRegionRequest) ProtoMessage() {}
const Default_CloseRegionRequest_TransitionIn_ZK bool = true
func (m *CloseRegionRequest) GetRegion() *RegionSpecifier {
if m != nil {
return m.Region
}
return nil
}
func (m *CloseRegionRequest) GetVersionOfClosingNode() uint32 {
if m != nil && m.VersionOfClosingNode != nil {
return *m.VersionOfClosingNode
}
return 0
}
func (m *CloseRegionRequest) GetTransitionIn_ZK() bool {
if m != nil && m.TransitionIn_ZK != nil {
return *m.TransitionIn_ZK
}
return Default_CloseRegionRequest_TransitionIn_ZK
}
func (m *CloseRegionRequest) GetDestinationServer() *ServerName {
if m != nil {
return m.DestinationServer
}
return nil
}
func (m *CloseRegionRequest) GetServerStartCode() uint64 {
if m != nil && m.ServerStartCode != nil {
return *m.ServerStartCode
}
return 0
}
type CloseRegionResponse struct {
Closed *bool `protobuf:"varint,1,req,name=closed" json:"closed,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CloseRegionResponse) Reset() { *m = CloseRegionResponse{} }
func (m *CloseRegionResponse) String() string { return proto1.CompactTextString(m) }
func (*CloseRegionResponse) ProtoMessage() {}
func (m *CloseRegionResponse) GetClosed() bool {
if m != nil && m.Closed != nil {
return *m.Closed
}
return false
}
// *
// Flushes the MemStore of the specified region.
// <p>
// This method is synchronous.
type FlushRegionRequest struct {
Region *RegionSpecifier `protobuf:"bytes,1,req,name=region" json:"region,omitempty"`
IfOlderThanTs *uint64 `protobuf:"varint,2,opt,name=if_older_than_ts" json:"if_older_than_ts,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FlushRegionRequest) Reset() { *m = FlushRegionRequest{} }
func (m *FlushRegionRequest) String() string { return proto1.CompactTextString(m) }
func (*FlushRegionRequest) ProtoMessage() {}
func (m *FlushRegionRequest) GetRegion() *RegionSpecifier {
if m != nil {
return m.Region
}
return nil
}
func (m *FlushRegionRequest) GetIfOlderThanTs() uint64 {
if m != nil && m.IfOlderThanTs != nil {
return *m.IfOlderThanTs
}
return 0
}
type FlushRegionResponse struct {
LastFlushTime *uint64 `protobuf:"varint,1,req,name=last_flush_time" json:"last_flush_time,omitempty"`
Flushed *bool `protobuf:"varint,2,opt,name=flushed" json:"flushed,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FlushRegionResponse) Reset() { *m = FlushRegionResponse{} }
func (m *FlushRegionResponse) String() string { return proto1.CompactTextString(m) }
func (*FlushRegionResponse) ProtoMessage() {}
func (m *FlushRegionResponse) GetLastFlushTime() uint64 {
if m != nil && m.LastFlushTime != nil {
return *m.LastFlushTime
}
return 0
}
func (m *FlushRegionResponse) GetFlushed() bool {
if m != nil && m.Flushed != nil {
return *m.Flushed
}
return false
}
// *
// Splits the specified region.
// <p>
// This method currently flushes the region and then forces a compaction which
// will then trigger a split. The flush is done synchronously but the
// compaction is asynchronous.
type SplitRegionRequest struct {
Region *RegionSpecifier `protobuf:"bytes,1,req,name=region" json:"region,omitempty"`
SplitPoint []byte `protobuf:"bytes,2,opt,name=split_point" json:"split_point,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SplitRegionRequest) Reset() { *m = SplitRegionRequest{} }
func (m *SplitRegionRequest) String() string { return proto1.CompactTextString(m) }
func (*SplitRegionRequest) ProtoMessage() {}
func (m *SplitRegionRequest) GetRegion() *RegionSpecifier {
if m != nil {
return m.Region
}
return nil
}
func (m *SplitRegionRequest) GetSplitPoint() []byte {
if m != nil {
return m.SplitPoint
}
return nil
}
type SplitRegionResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *SplitRegionResponse) Reset() { *m = SplitRegionResponse{} }
func (m *SplitRegionResponse) String() string { return proto1.CompactTextString(m) }
func (*SplitRegionResponse) ProtoMessage() {}
// *
// Compacts the specified region. Performs a major compaction if specified.
// <p>
// This method is asynchronous.
type CompactRegionRequest struct {
Region *RegionSpecifier `protobuf:"bytes,1,req,name=region" json:"region,omitempty"`
Major *bool `protobuf:"varint,2,opt,name=major" json:"major,omitempty"`
Family []byte `protobuf:"bytes,3,opt,name=family" json:"family,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CompactRegionRequest) Reset() { *m = CompactRegionRequest{} }
func (m *CompactRegionRequest) String() string { return proto1.CompactTextString(m) }
func (*CompactRegionRequest) ProtoMessage() {}
func (m *CompactRegionRequest) GetRegion() *RegionSpecifier {
if m != nil {
return m.Region
}
return nil
}
func (m *CompactRegionRequest) GetMajor() bool {
if m != nil && m.Major != nil {
return *m.Major
}
return false
}
func (m *CompactRegionRequest) GetFamily() []byte {
if m != nil {
return m.Family
}
return nil
}
type CompactRegionResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *CompactRegionResponse) Reset() { *m = CompactRegionResponse{} }
func (m *CompactRegionResponse) String() string { return proto1.CompactTextString(m) }
func (*CompactRegionResponse) ProtoMessage() {}
type UpdateFavoredNodesRequest struct {
UpdateInfo []*UpdateFavoredNodesRequest_RegionUpdateInfo `protobuf:"bytes,1,rep,name=update_info" json:"update_info,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *UpdateFavoredNodesRequest) Reset() { *m = UpdateFavoredNodesRequest{} }
func (m *UpdateFavoredNodesRequest) String() string { return proto1.CompactTextString(m) }
func (*UpdateFavoredNodesRequest) ProtoMessage() {}
func (m *UpdateFavoredNodesRequest) GetUpdateInfo() []*UpdateFavoredNodesRequest_RegionUpdateInfo {
if m != nil {
return m.UpdateInfo
}
return nil
}
type UpdateFavoredNodesRequest_RegionUpdateInfo struct {
Region *RegionInfo `protobuf:"bytes,1,req,name=region" json:"region,omitempty"`
FavoredNodes []*ServerName `protobuf:"bytes,2,rep,name=favored_nodes" json:"favored_nodes,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *UpdateFavoredNodesRequest_RegionUpdateInfo) Reset() {
*m = UpdateFavoredNodesRequest_RegionUpdateInfo{}
}
func (m *UpdateFavoredNodesRequest_RegionUpdateInfo) String() string {
return proto1.CompactTextString(m)
}
func (*UpdateFavoredNodesRequest_RegionUpdateInfo) ProtoMessage() {}
func (m *UpdateFavoredNodesRequest_RegionUpdateInfo) GetRegion() *RegionInfo {
if m != nil {
return m.Region
}
return nil
}
func (m *UpdateFavoredNodesRequest_RegionUpdateInfo) GetFavoredNodes() []*ServerName {
if m != nil {
return m.FavoredNodes
}
return nil
}
type UpdateFavoredNodesResponse struct {
Response *uint32 `protobuf:"varint,1,opt,name=response" json:"response,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *UpdateFavoredNodesResponse) Reset() { *m = UpdateFavoredNodesResponse{} }
func (m *UpdateFavoredNodesResponse) String() string { return proto1.CompactTextString(m) }
func (*UpdateFavoredNodesResponse) ProtoMessage() {}
func (m *UpdateFavoredNodesResponse) GetResponse() uint32 {
if m != nil && m.Response != nil {
return *m.Response
}
return 0
}
// *
// Merges the specified regions.
// <p>
// This method currently closes the regions and then merges them
type MergeRegionsRequest struct {
RegionA *RegionSpecifier `protobuf:"bytes,1,req,name=region_a" json:"region_a,omitempty"`
RegionB *RegionSpecifier `protobuf:"bytes,2,req,name=region_b" json:"region_b,omitempty"`
Forcible *bool `protobuf:"varint,3,opt,name=forcible,def=0" json:"forcible,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *MergeRegionsRequest) Reset() { *m = MergeRegionsRequest{} }
func (m *MergeRegionsRequest) String() string { return proto1.CompactTextString(m) }
func (*MergeRegionsRequest) ProtoMessage() {}
const Default_MergeRegionsRequest_Forcible bool = false
func (m *MergeRegionsRequest) GetRegionA() *RegionSpecifier {
if m != nil {
return m.RegionA
}
return nil
}
func (m *MergeRegionsRequest) GetRegionB() *RegionSpecifier {
if m != nil {
return m.RegionB
}
return nil
}
func (m *MergeRegionsRequest) GetForcible() bool {
if m != nil && m.Forcible != nil {
return *m.Forcible
}
return Default_MergeRegionsRequest_Forcible
}
type MergeRegionsResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *MergeRegionsResponse) Reset() { *m = MergeRegionsResponse{} }
func (m *MergeRegionsResponse) String() string { return proto1.CompactTextString(m) }
func (*MergeRegionsResponse) ProtoMessage() {}
// Protocol buffer version of WAL for replication
type WALEntry struct {
Key *WALKey `protobuf:"bytes,1,req,name=key" json:"key,omitempty"`
// Following may be null if the KVs/Cells are carried along the side in a cellblock (See
// RPC for more on cellblocks). If Cells/KVs are in a cellblock, this next field is null
// and associated_cell_count has count of Cells associated w/ this WALEntry
KeyValueBytes [][]byte `protobuf:"bytes,2,rep,name=key_value_bytes" json:"key_value_bytes,omitempty"`
// If Cell data is carried alongside in a cellblock, this is count of Cells in the cellblock.
AssociatedCellCount *int32 `protobuf:"varint,3,opt,name=associated_cell_count" json:"associated_cell_count,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *WALEntry) Reset() { *m = WALEntry{} }
func (m *WALEntry) String() string { return proto1.CompactTextString(m) }
func (*WALEntry) ProtoMessage() {}
func (m *WALEntry) GetKey() *WALKey {
if m != nil {
return m.Key
}
return nil
}
func (m *WALEntry) GetKeyValueBytes() [][]byte {
if m != nil {
return m.KeyValueBytes
}
return nil
}
func (m *WALEntry) GetAssociatedCellCount() int32 {
if m != nil && m.AssociatedCellCount != nil {
return *m.AssociatedCellCount
}
return 0
}
// *
// Replicates the given entries. The guarantee is that the given entries
// will be durable on the slave cluster if this method returns without
// any exception. hbase.replication has to be set to true for this to work.
type ReplicateWALEntryRequest struct {
Entry []*WALEntry `protobuf:"bytes,1,rep,name=entry" json:"entry,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ReplicateWALEntryRequest) Reset() { *m = ReplicateWALEntryRequest{} }
func (m *ReplicateWALEntryRequest) String() string { return proto1.CompactTextString(m) }
func (*ReplicateWALEntryRequest) ProtoMessage() {}
func (m *ReplicateWALEntryRequest) GetEntry() []*WALEntry {
if m != nil {
return m.Entry
}
return nil
}
type ReplicateWALEntryResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *ReplicateWALEntryResponse) Reset() { *m = ReplicateWALEntryResponse{} }
func (m *ReplicateWALEntryResponse) String() string { return proto1.CompactTextString(m) }
func (*ReplicateWALEntryResponse) ProtoMessage() {}
type RollWALWriterRequest struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *RollWALWriterRequest) Reset() { *m = RollWALWriterRequest{} }
func (m *RollWALWriterRequest) String() string { return proto1.CompactTextString(m) }
func (*RollWALWriterRequest) ProtoMessage() {}
type RollWALWriterResponse struct {
// A list of encoded name of regions to flush
RegionToFlush [][]byte `protobuf:"bytes,1,rep,name=region_to_flush" json:"region_to_flush,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RollWALWriterResponse) Reset() { *m = RollWALWriterResponse{} }
func (m *RollWALWriterResponse) String() string { return proto1.CompactTextString(m) }
func (*RollWALWriterResponse) ProtoMessage() {}
func (m *RollWALWriterResponse) GetRegionToFlush() [][]byte {
if m != nil {
return m.RegionToFlush
}
return nil
}
type StopServerRequest struct {
Reason *string `protobuf:"bytes,1,req,name=reason" json:"reason,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *StopServerRequest) Reset() { *m = StopServerRequest{} }
func (m *StopServerRequest) String() string { return proto1.CompactTextString(m) }
func (*StopServerRequest) ProtoMessage() {}
func (m *StopServerRequest) GetReason() string {
if m != nil && m.Reason != nil {
return *m.Reason
}
return ""
}
type StopServerResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *StopServerResponse) Reset() { *m = StopServerResponse{} }
func (m *StopServerResponse) String() string { return proto1.CompactTextString(m) }
func (*StopServerResponse) ProtoMessage() {}
type GetServerInfoRequest struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *GetServerInfoRequest) Reset() { *m = GetServerInfoRequest{} }
func (m *GetServerInfoRequest) String() string { return proto1.CompactTextString(m) }
func (*GetServerInfoRequest) ProtoMessage() {}
type ServerInfo struct {
ServerName *ServerName `protobuf:"bytes,1,req,name=server_name" json:"server_name,omitempty"`
WebuiPort *uint32 `protobuf:"varint,2,opt,name=webui_port" json:"webui_port,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ServerInfo) Reset() { *m = ServerInfo{} }
func (m *ServerInfo) String() string { return proto1.CompactTextString(m) }
func (*ServerInfo) ProtoMessage() {}
func (m *ServerInfo) GetServerName() *ServerName {
if m != nil {
return m.ServerName
}
return nil
}
func (m *ServerInfo) GetWebuiPort() uint32 {
if m != nil && m.WebuiPort != nil {
return *m.WebuiPort
}
return 0
}
type GetServerInfoResponse struct {
ServerInfo *ServerInfo `protobuf:"bytes,1,req,name=server_info" json:"server_info,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetServerInfoResponse) Reset() { *m = GetServerInfoResponse{} }
func (m *GetServerInfoResponse) String() string { return proto1.CompactTextString(m) }
func (*GetServerInfoResponse) ProtoMessage() {}
func (m *GetServerInfoResponse) GetServerInfo() *ServerInfo {
if m != nil {
return m.ServerInfo
}
return nil
}
func init() {
proto1.RegisterEnum("proto.GetRegionInfoResponse_CompactionState", GetRegionInfoResponse_CompactionState_name, GetRegionInfoResponse_CompactionState_value)
proto1.RegisterEnum("proto.OpenRegionResponse_RegionOpeningState", OpenRegionResponse_RegionOpeningState_name, OpenRegionResponse_RegionOpeningState_value)
}

View file

@ -0,0 +1,82 @@
// Code generated by protoc-gen-go.
// source: Aggregate.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type AggregateRequest struct {
// * The request passed to the AggregateService consists of three parts
// (1) the (canonical) classname of the ColumnInterpreter implementation
// (2) the Scan query
// (3) any bytes required to construct the ColumnInterpreter object
// properly
InterpreterClassName *string `protobuf:"bytes,1,req,name=interpreter_class_name" json:"interpreter_class_name,omitempty"`
Scan *Scan `protobuf:"bytes,2,req,name=scan" json:"scan,omitempty"`
InterpreterSpecificBytes []byte `protobuf:"bytes,3,opt,name=interpreter_specific_bytes" json:"interpreter_specific_bytes,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *AggregateRequest) Reset() { *m = AggregateRequest{} }
func (m *AggregateRequest) String() string { return proto1.CompactTextString(m) }
func (*AggregateRequest) ProtoMessage() {}
func (m *AggregateRequest) GetInterpreterClassName() string {
if m != nil && m.InterpreterClassName != nil {
return *m.InterpreterClassName
}
return ""
}
func (m *AggregateRequest) GetScan() *Scan {
if m != nil {
return m.Scan
}
return nil
}
func (m *AggregateRequest) GetInterpreterSpecificBytes() []byte {
if m != nil {
return m.InterpreterSpecificBytes
}
return nil
}
type AggregateResponse struct {
// *
// The AggregateService methods all have a response that either is a Pair
// or a simple object. When it is a Pair both first_part and second_part
// have defined values (and the second_part is not present in the response
// when the response is not a pair). Refer to the AggregateImplementation
// class for an overview of the AggregateResponse object constructions.
FirstPart [][]byte `protobuf:"bytes,1,rep,name=first_part" json:"first_part,omitempty"`
SecondPart []byte `protobuf:"bytes,2,opt,name=second_part" json:"second_part,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *AggregateResponse) Reset() { *m = AggregateResponse{} }
func (m *AggregateResponse) String() string { return proto1.CompactTextString(m) }
func (*AggregateResponse) ProtoMessage() {}
func (m *AggregateResponse) GetFirstPart() [][]byte {
if m != nil {
return m.FirstPart
}
return nil
}
func (m *AggregateResponse) GetSecondPart() []byte {
if m != nil {
return m.SecondPart
}
return nil
}
func init() {
}

View file

@ -0,0 +1,228 @@
// Code generated by protoc-gen-go.
// source: Authentication.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type TokenIdentifier_Kind int32
const (
TokenIdentifier_HBASE_AUTH_TOKEN TokenIdentifier_Kind = 0
)
var TokenIdentifier_Kind_name = map[int32]string{
0: "HBASE_AUTH_TOKEN",
}
var TokenIdentifier_Kind_value = map[string]int32{
"HBASE_AUTH_TOKEN": 0,
}
func (x TokenIdentifier_Kind) Enum() *TokenIdentifier_Kind {
p := new(TokenIdentifier_Kind)
*p = x
return p
}
func (x TokenIdentifier_Kind) String() string {
return proto1.EnumName(TokenIdentifier_Kind_name, int32(x))
}
func (x *TokenIdentifier_Kind) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(TokenIdentifier_Kind_value, data, "TokenIdentifier_Kind")
if err != nil {
return err
}
*x = TokenIdentifier_Kind(value)
return nil
}
type AuthenticationKey struct {
Id *int32 `protobuf:"varint,1,req,name=id" json:"id,omitempty"`
ExpirationDate *int64 `protobuf:"varint,2,req,name=expiration_date" json:"expiration_date,omitempty"`
Key []byte `protobuf:"bytes,3,req,name=key" json:"key,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *AuthenticationKey) Reset() { *m = AuthenticationKey{} }
func (m *AuthenticationKey) String() string { return proto1.CompactTextString(m) }
func (*AuthenticationKey) ProtoMessage() {}
func (m *AuthenticationKey) GetId() int32 {
if m != nil && m.Id != nil {
return *m.Id
}
return 0
}
func (m *AuthenticationKey) GetExpirationDate() int64 {
if m != nil && m.ExpirationDate != nil {
return *m.ExpirationDate
}
return 0
}
func (m *AuthenticationKey) GetKey() []byte {
if m != nil {
return m.Key
}
return nil
}
type TokenIdentifier struct {
Kind *TokenIdentifier_Kind `protobuf:"varint,1,req,name=kind,enum=proto.TokenIdentifier_Kind" json:"kind,omitempty"`
Username []byte `protobuf:"bytes,2,req,name=username" json:"username,omitempty"`
KeyId *int32 `protobuf:"varint,3,req,name=key_id" json:"key_id,omitempty"`
IssueDate *int64 `protobuf:"varint,4,opt,name=issue_date" json:"issue_date,omitempty"`
ExpirationDate *int64 `protobuf:"varint,5,opt,name=expiration_date" json:"expiration_date,omitempty"`
SequenceNumber *int64 `protobuf:"varint,6,opt,name=sequence_number" json:"sequence_number,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *TokenIdentifier) Reset() { *m = TokenIdentifier{} }
func (m *TokenIdentifier) String() string { return proto1.CompactTextString(m) }
func (*TokenIdentifier) ProtoMessage() {}
func (m *TokenIdentifier) GetKind() TokenIdentifier_Kind {
if m != nil && m.Kind != nil {
return *m.Kind
}
return TokenIdentifier_HBASE_AUTH_TOKEN
}
func (m *TokenIdentifier) GetUsername() []byte {
if m != nil {
return m.Username
}
return nil
}
func (m *TokenIdentifier) GetKeyId() int32 {
if m != nil && m.KeyId != nil {
return *m.KeyId
}
return 0
}
func (m *TokenIdentifier) GetIssueDate() int64 {
if m != nil && m.IssueDate != nil {
return *m.IssueDate
}
return 0
}
func (m *TokenIdentifier) GetExpirationDate() int64 {
if m != nil && m.ExpirationDate != nil {
return *m.ExpirationDate
}
return 0
}
func (m *TokenIdentifier) GetSequenceNumber() int64 {
if m != nil && m.SequenceNumber != nil {
return *m.SequenceNumber
}
return 0
}
// Serialization of the org.apache.hadoop.security.token.Token class
// Note that this is a Hadoop class, so fields may change!
type Token struct {
// the TokenIdentifier in serialized form
// Note: we can't use the protobuf directly because the Hadoop Token class
// only stores the serialized bytes
Identifier []byte `protobuf:"bytes,1,opt,name=identifier" json:"identifier,omitempty"`
Password []byte `protobuf:"bytes,2,opt,name=password" json:"password,omitempty"`
Service []byte `protobuf:"bytes,3,opt,name=service" json:"service,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Token) Reset() { *m = Token{} }
func (m *Token) String() string { return proto1.CompactTextString(m) }
func (*Token) ProtoMessage() {}
func (m *Token) GetIdentifier() []byte {
if m != nil {
return m.Identifier
}
return nil
}
func (m *Token) GetPassword() []byte {
if m != nil {
return m.Password
}
return nil
}
func (m *Token) GetService() []byte {
if m != nil {
return m.Service
}
return nil
}
// RPC request & response messages
type GetAuthenticationTokenRequest struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *GetAuthenticationTokenRequest) Reset() { *m = GetAuthenticationTokenRequest{} }
func (m *GetAuthenticationTokenRequest) String() string { return proto1.CompactTextString(m) }
func (*GetAuthenticationTokenRequest) ProtoMessage() {}
type GetAuthenticationTokenResponse struct {
Token *Token `protobuf:"bytes,1,opt,name=token" json:"token,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetAuthenticationTokenResponse) Reset() { *m = GetAuthenticationTokenResponse{} }
func (m *GetAuthenticationTokenResponse) String() string { return proto1.CompactTextString(m) }
func (*GetAuthenticationTokenResponse) ProtoMessage() {}
func (m *GetAuthenticationTokenResponse) GetToken() *Token {
if m != nil {
return m.Token
}
return nil
}
type WhoAmIRequest struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *WhoAmIRequest) Reset() { *m = WhoAmIRequest{} }
func (m *WhoAmIRequest) String() string { return proto1.CompactTextString(m) }
func (*WhoAmIRequest) ProtoMessage() {}
type WhoAmIResponse struct {
Username *string `protobuf:"bytes,1,opt,name=username" json:"username,omitempty"`
AuthMethod *string `protobuf:"bytes,2,opt,name=auth_method" json:"auth_method,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *WhoAmIResponse) Reset() { *m = WhoAmIResponse{} }
func (m *WhoAmIResponse) String() string { return proto1.CompactTextString(m) }
func (*WhoAmIResponse) ProtoMessage() {}
func (m *WhoAmIResponse) GetUsername() string {
if m != nil && m.Username != nil {
return *m.Username
}
return ""
}
func (m *WhoAmIResponse) GetAuthMethod() string {
if m != nil && m.AuthMethod != nil {
return *m.AuthMethod
}
return ""
}
func init() {
proto1.RegisterEnum("proto.TokenIdentifier_Kind", TokenIdentifier_Kind_name, TokenIdentifier_Kind_value)
}

197
vendor/github.com/pingcap/go-hbase/proto/Cell.pb.go generated vendored Normal file
View file

@ -0,0 +1,197 @@
// Code generated by protoc-gen-go.
// source: Cell.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
// *
// The type of the key in a Cell
type CellType int32
const (
CellType_MINIMUM CellType = 0
CellType_PUT CellType = 4
CellType_DELETE CellType = 8
CellType_DELETE_COLUMN CellType = 12
CellType_DELETE_FAMILY CellType = 14
// MAXIMUM is used when searching; you look from maximum on down.
CellType_MAXIMUM CellType = 255
)
var CellType_name = map[int32]string{
0: "MINIMUM",
4: "PUT",
8: "DELETE",
12: "DELETE_COLUMN",
14: "DELETE_FAMILY",
255: "MAXIMUM",
}
var CellType_value = map[string]int32{
"MINIMUM": 0,
"PUT": 4,
"DELETE": 8,
"DELETE_COLUMN": 12,
"DELETE_FAMILY": 14,
"MAXIMUM": 255,
}
func (x CellType) Enum() *CellType {
p := new(CellType)
*p = x
return p
}
func (x CellType) String() string {
return proto1.EnumName(CellType_name, int32(x))
}
func (x *CellType) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(CellType_value, data, "CellType")
if err != nil {
return err
}
*x = CellType(value)
return nil
}
// *
// Protocol buffer version of Cell.
type Cell struct {
Row []byte `protobuf:"bytes,1,opt,name=row" json:"row,omitempty"`
Family []byte `protobuf:"bytes,2,opt,name=family" json:"family,omitempty"`
Qualifier []byte `protobuf:"bytes,3,opt,name=qualifier" json:"qualifier,omitempty"`
Timestamp *uint64 `protobuf:"varint,4,opt,name=timestamp" json:"timestamp,omitempty"`
CellType *CellType `protobuf:"varint,5,opt,name=cell_type,enum=proto.CellType" json:"cell_type,omitempty"`
Value []byte `protobuf:"bytes,6,opt,name=value" json:"value,omitempty"`
Tags []byte `protobuf:"bytes,7,opt,name=tags" json:"tags,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Cell) Reset() { *m = Cell{} }
func (m *Cell) String() string { return proto1.CompactTextString(m) }
func (*Cell) ProtoMessage() {}
func (m *Cell) GetRow() []byte {
if m != nil {
return m.Row
}
return nil
}
func (m *Cell) GetFamily() []byte {
if m != nil {
return m.Family
}
return nil
}
func (m *Cell) GetQualifier() []byte {
if m != nil {
return m.Qualifier
}
return nil
}
func (m *Cell) GetTimestamp() uint64 {
if m != nil && m.Timestamp != nil {
return *m.Timestamp
}
return 0
}
func (m *Cell) GetCellType() CellType {
if m != nil && m.CellType != nil {
return *m.CellType
}
return CellType_MINIMUM
}
func (m *Cell) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
func (m *Cell) GetTags() []byte {
if m != nil {
return m.Tags
}
return nil
}
// *
// Protocol buffer version of KeyValue.
// It doesn't have those transient parameters
type KeyValue struct {
Row []byte `protobuf:"bytes,1,req,name=row" json:"row,omitempty"`
Family []byte `protobuf:"bytes,2,req,name=family" json:"family,omitempty"`
Qualifier []byte `protobuf:"bytes,3,req,name=qualifier" json:"qualifier,omitempty"`
Timestamp *uint64 `protobuf:"varint,4,opt,name=timestamp" json:"timestamp,omitempty"`
KeyType *CellType `protobuf:"varint,5,opt,name=key_type,enum=proto.CellType" json:"key_type,omitempty"`
Value []byte `protobuf:"bytes,6,opt,name=value" json:"value,omitempty"`
Tags []byte `protobuf:"bytes,7,opt,name=tags" json:"tags,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *KeyValue) Reset() { *m = KeyValue{} }
func (m *KeyValue) String() string { return proto1.CompactTextString(m) }
func (*KeyValue) ProtoMessage() {}
func (m *KeyValue) GetRow() []byte {
if m != nil {
return m.Row
}
return nil
}
func (m *KeyValue) GetFamily() []byte {
if m != nil {
return m.Family
}
return nil
}
func (m *KeyValue) GetQualifier() []byte {
if m != nil {
return m.Qualifier
}
return nil
}
func (m *KeyValue) GetTimestamp() uint64 {
if m != nil && m.Timestamp != nil {
return *m.Timestamp
}
return 0
}
func (m *KeyValue) GetKeyType() CellType {
if m != nil && m.KeyType != nil {
return *m.KeyType
}
return CellType_MINIMUM
}
func (m *KeyValue) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
func (m *KeyValue) GetTags() []byte {
if m != nil {
return m.Tags
}
return nil
}
func init() {
proto1.RegisterEnum("proto.CellType", CellType_name, CellType_value)
}

1411
vendor/github.com/pingcap/go-hbase/proto/Client.pb.go generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,35 @@
// Code generated by protoc-gen-go.
// source: ClusterId.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
// *
// Content of the '/hbase/hbaseid', cluster id, znode.
// Also cluster of the ${HBASE_ROOTDIR}/hbase.id file.
type ClusterId struct {
// This is the cluster id, a uuid as a String
ClusterId *string `protobuf:"bytes,1,req,name=cluster_id" json:"cluster_id,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ClusterId) Reset() { *m = ClusterId{} }
func (m *ClusterId) String() string { return proto1.CompactTextString(m) }
func (*ClusterId) ProtoMessage() {}
func (m *ClusterId) GetClusterId() string {
if m != nil && m.ClusterId != nil {
return *m.ClusterId
}
return ""
}
func init() {
}

View file

@ -0,0 +1,597 @@
// Code generated by protoc-gen-go.
// source: ClusterStatus.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type RegionState_State int32
const (
RegionState_OFFLINE RegionState_State = 0
RegionState_PENDING_OPEN RegionState_State = 1
RegionState_OPENING RegionState_State = 2
RegionState_OPEN RegionState_State = 3
RegionState_PENDING_CLOSE RegionState_State = 4
RegionState_CLOSING RegionState_State = 5
RegionState_CLOSED RegionState_State = 6
RegionState_SPLITTING RegionState_State = 7
RegionState_SPLIT RegionState_State = 8
RegionState_FAILED_OPEN RegionState_State = 9
RegionState_FAILED_CLOSE RegionState_State = 10
RegionState_MERGING RegionState_State = 11
RegionState_MERGED RegionState_State = 12
RegionState_SPLITTING_NEW RegionState_State = 13
// region but hasn't be created yet, or master doesn't
// know it's already created
RegionState_MERGING_NEW RegionState_State = 14
)
var RegionState_State_name = map[int32]string{
0: "OFFLINE",
1: "PENDING_OPEN",
2: "OPENING",
3: "OPEN",
4: "PENDING_CLOSE",
5: "CLOSING",
6: "CLOSED",
7: "SPLITTING",
8: "SPLIT",
9: "FAILED_OPEN",
10: "FAILED_CLOSE",
11: "MERGING",
12: "MERGED",
13: "SPLITTING_NEW",
14: "MERGING_NEW",
}
var RegionState_State_value = map[string]int32{
"OFFLINE": 0,
"PENDING_OPEN": 1,
"OPENING": 2,
"OPEN": 3,
"PENDING_CLOSE": 4,
"CLOSING": 5,
"CLOSED": 6,
"SPLITTING": 7,
"SPLIT": 8,
"FAILED_OPEN": 9,
"FAILED_CLOSE": 10,
"MERGING": 11,
"MERGED": 12,
"SPLITTING_NEW": 13,
"MERGING_NEW": 14,
}
func (x RegionState_State) Enum() *RegionState_State {
p := new(RegionState_State)
*p = x
return p
}
func (x RegionState_State) String() string {
return proto1.EnumName(RegionState_State_name, int32(x))
}
func (x *RegionState_State) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(RegionState_State_value, data, "RegionState_State")
if err != nil {
return err
}
*x = RegionState_State(value)
return nil
}
type RegionState struct {
RegionInfo *RegionInfo `protobuf:"bytes,1,req,name=region_info" json:"region_info,omitempty"`
State *RegionState_State `protobuf:"varint,2,req,name=state,enum=proto.RegionState_State" json:"state,omitempty"`
Stamp *uint64 `protobuf:"varint,3,opt,name=stamp" json:"stamp,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionState) Reset() { *m = RegionState{} }
func (m *RegionState) String() string { return proto1.CompactTextString(m) }
func (*RegionState) ProtoMessage() {}
func (m *RegionState) GetRegionInfo() *RegionInfo {
if m != nil {
return m.RegionInfo
}
return nil
}
func (m *RegionState) GetState() RegionState_State {
if m != nil && m.State != nil {
return *m.State
}
return RegionState_OFFLINE
}
func (m *RegionState) GetStamp() uint64 {
if m != nil && m.Stamp != nil {
return *m.Stamp
}
return 0
}
type RegionInTransition struct {
Spec *RegionSpecifier `protobuf:"bytes,1,req,name=spec" json:"spec,omitempty"`
RegionState *RegionState `protobuf:"bytes,2,req,name=region_state" json:"region_state,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionInTransition) Reset() { *m = RegionInTransition{} }
func (m *RegionInTransition) String() string { return proto1.CompactTextString(m) }
func (*RegionInTransition) ProtoMessage() {}
func (m *RegionInTransition) GetSpec() *RegionSpecifier {
if m != nil {
return m.Spec
}
return nil
}
func (m *RegionInTransition) GetRegionState() *RegionState {
if m != nil {
return m.RegionState
}
return nil
}
type RegionLoad struct {
// * the region specifier
RegionSpecifier *RegionSpecifier `protobuf:"bytes,1,req,name=region_specifier" json:"region_specifier,omitempty"`
// * the number of stores for the region
Stores *uint32 `protobuf:"varint,2,opt,name=stores" json:"stores,omitempty"`
// * the number of storefiles for the region
Storefiles *uint32 `protobuf:"varint,3,opt,name=storefiles" json:"storefiles,omitempty"`
// * the total size of the store files for the region, uncompressed, in MB
StoreUncompressedSize_MB *uint32 `protobuf:"varint,4,opt,name=store_uncompressed_size_MB" json:"store_uncompressed_size_MB,omitempty"`
// * the current total size of the store files for the region, in MB
StorefileSize_MB *uint32 `protobuf:"varint,5,opt,name=storefile_size_MB" json:"storefile_size_MB,omitempty"`
// * the current size of the memstore for the region, in MB
MemstoreSize_MB *uint32 `protobuf:"varint,6,opt,name=memstore_size_MB" json:"memstore_size_MB,omitempty"`
// *
// The current total size of root-level store file indexes for the region,
// in MB. The same as {@link #rootIndexSizeKB} but in MB.
StorefileIndexSize_MB *uint32 `protobuf:"varint,7,opt,name=storefile_index_size_MB" json:"storefile_index_size_MB,omitempty"`
// * the current total read requests made to region
ReadRequestsCount *uint64 `protobuf:"varint,8,opt,name=read_requests_count" json:"read_requests_count,omitempty"`
// * the current total write requests made to region
WriteRequestsCount *uint64 `protobuf:"varint,9,opt,name=write_requests_count" json:"write_requests_count,omitempty"`
// * the total compacting key values in currently running compaction
TotalCompacting_KVs *uint64 `protobuf:"varint,10,opt,name=total_compacting_KVs" json:"total_compacting_KVs,omitempty"`
// * the completed count of key values in currently running compaction
CurrentCompacted_KVs *uint64 `protobuf:"varint,11,opt,name=current_compacted_KVs" json:"current_compacted_KVs,omitempty"`
// * The current total size of root-level indexes for the region, in KB.
RootIndexSize_KB *uint32 `protobuf:"varint,12,opt,name=root_index_size_KB" json:"root_index_size_KB,omitempty"`
// * The total size of all index blocks, not just the root level, in KB.
TotalStaticIndexSize_KB *uint32 `protobuf:"varint,13,opt,name=total_static_index_size_KB" json:"total_static_index_size_KB,omitempty"`
// *
// The total size of all Bloom filter blocks, not just loaded into the
// block cache, in KB.
TotalStaticBloomSize_KB *uint32 `protobuf:"varint,14,opt,name=total_static_bloom_size_KB" json:"total_static_bloom_size_KB,omitempty"`
// * the most recent sequence Id from cache flush
CompleteSequenceId *uint64 `protobuf:"varint,15,opt,name=complete_sequence_id" json:"complete_sequence_id,omitempty"`
// * The current data locality for region in the regionserver
DataLocality *float32 `protobuf:"fixed32,16,opt,name=data_locality" json:"data_locality,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionLoad) Reset() { *m = RegionLoad{} }
func (m *RegionLoad) String() string { return proto1.CompactTextString(m) }
func (*RegionLoad) ProtoMessage() {}
func (m *RegionLoad) GetRegionSpecifier() *RegionSpecifier {
if m != nil {
return m.RegionSpecifier
}
return nil
}
func (m *RegionLoad) GetStores() uint32 {
if m != nil && m.Stores != nil {
return *m.Stores
}
return 0
}
func (m *RegionLoad) GetStorefiles() uint32 {
if m != nil && m.Storefiles != nil {
return *m.Storefiles
}
return 0
}
func (m *RegionLoad) GetStoreUncompressedSize_MB() uint32 {
if m != nil && m.StoreUncompressedSize_MB != nil {
return *m.StoreUncompressedSize_MB
}
return 0
}
func (m *RegionLoad) GetStorefileSize_MB() uint32 {
if m != nil && m.StorefileSize_MB != nil {
return *m.StorefileSize_MB
}
return 0
}
func (m *RegionLoad) GetMemstoreSize_MB() uint32 {
if m != nil && m.MemstoreSize_MB != nil {
return *m.MemstoreSize_MB
}
return 0
}
func (m *RegionLoad) GetStorefileIndexSize_MB() uint32 {
if m != nil && m.StorefileIndexSize_MB != nil {
return *m.StorefileIndexSize_MB
}
return 0
}
func (m *RegionLoad) GetReadRequestsCount() uint64 {
if m != nil && m.ReadRequestsCount != nil {
return *m.ReadRequestsCount
}
return 0
}
func (m *RegionLoad) GetWriteRequestsCount() uint64 {
if m != nil && m.WriteRequestsCount != nil {
return *m.WriteRequestsCount
}
return 0
}
func (m *RegionLoad) GetTotalCompacting_KVs() uint64 {
if m != nil && m.TotalCompacting_KVs != nil {
return *m.TotalCompacting_KVs
}
return 0
}
func (m *RegionLoad) GetCurrentCompacted_KVs() uint64 {
if m != nil && m.CurrentCompacted_KVs != nil {
return *m.CurrentCompacted_KVs
}
return 0
}
func (m *RegionLoad) GetRootIndexSize_KB() uint32 {
if m != nil && m.RootIndexSize_KB != nil {
return *m.RootIndexSize_KB
}
return 0
}
func (m *RegionLoad) GetTotalStaticIndexSize_KB() uint32 {
if m != nil && m.TotalStaticIndexSize_KB != nil {
return *m.TotalStaticIndexSize_KB
}
return 0
}
func (m *RegionLoad) GetTotalStaticBloomSize_KB() uint32 {
if m != nil && m.TotalStaticBloomSize_KB != nil {
return *m.TotalStaticBloomSize_KB
}
return 0
}
func (m *RegionLoad) GetCompleteSequenceId() uint64 {
if m != nil && m.CompleteSequenceId != nil {
return *m.CompleteSequenceId
}
return 0
}
func (m *RegionLoad) GetDataLocality() float32 {
if m != nil && m.DataLocality != nil {
return *m.DataLocality
}
return 0
}
type ReplicationLoadSink struct {
AgeOfLastAppliedOp *uint64 `protobuf:"varint,1,req,name=ageOfLastAppliedOp" json:"ageOfLastAppliedOp,omitempty"`
TimeStampsOfLastAppliedOp *uint64 `protobuf:"varint,2,req,name=timeStampsOfLastAppliedOp" json:"timeStampsOfLastAppliedOp,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ReplicationLoadSink) Reset() { *m = ReplicationLoadSink{} }
func (m *ReplicationLoadSink) String() string { return proto1.CompactTextString(m) }
func (*ReplicationLoadSink) ProtoMessage() {}
func (m *ReplicationLoadSink) GetAgeOfLastAppliedOp() uint64 {
if m != nil && m.AgeOfLastAppliedOp != nil {
return *m.AgeOfLastAppliedOp
}
return 0
}
func (m *ReplicationLoadSink) GetTimeStampsOfLastAppliedOp() uint64 {
if m != nil && m.TimeStampsOfLastAppliedOp != nil {
return *m.TimeStampsOfLastAppliedOp
}
return 0
}
type ReplicationLoadSource struct {
PeerID *string `protobuf:"bytes,1,req,name=peerID" json:"peerID,omitempty"`
AgeOfLastShippedOp *uint64 `protobuf:"varint,2,req,name=ageOfLastShippedOp" json:"ageOfLastShippedOp,omitempty"`
SizeOfLogQueue *uint32 `protobuf:"varint,3,req,name=sizeOfLogQueue" json:"sizeOfLogQueue,omitempty"`
TimeStampOfLastShippedOp *uint64 `protobuf:"varint,4,req,name=timeStampOfLastShippedOp" json:"timeStampOfLastShippedOp,omitempty"`
ReplicationLag *uint64 `protobuf:"varint,5,req,name=replicationLag" json:"replicationLag,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ReplicationLoadSource) Reset() { *m = ReplicationLoadSource{} }
func (m *ReplicationLoadSource) String() string { return proto1.CompactTextString(m) }
func (*ReplicationLoadSource) ProtoMessage() {}
func (m *ReplicationLoadSource) GetPeerID() string {
if m != nil && m.PeerID != nil {
return *m.PeerID
}
return ""
}
func (m *ReplicationLoadSource) GetAgeOfLastShippedOp() uint64 {
if m != nil && m.AgeOfLastShippedOp != nil {
return *m.AgeOfLastShippedOp
}
return 0
}
func (m *ReplicationLoadSource) GetSizeOfLogQueue() uint32 {
if m != nil && m.SizeOfLogQueue != nil {
return *m.SizeOfLogQueue
}
return 0
}
func (m *ReplicationLoadSource) GetTimeStampOfLastShippedOp() uint64 {
if m != nil && m.TimeStampOfLastShippedOp != nil {
return *m.TimeStampOfLastShippedOp
}
return 0
}
func (m *ReplicationLoadSource) GetReplicationLag() uint64 {
if m != nil && m.ReplicationLag != nil {
return *m.ReplicationLag
}
return 0
}
type ServerLoad struct {
// * Number of requests since last report.
NumberOfRequests *uint32 `protobuf:"varint,1,opt,name=number_of_requests" json:"number_of_requests,omitempty"`
// * Total Number of requests from the start of the region server.
TotalNumberOfRequests *uint32 `protobuf:"varint,2,opt,name=total_number_of_requests" json:"total_number_of_requests,omitempty"`
// * the amount of used heap, in MB.
UsedHeap_MB *uint32 `protobuf:"varint,3,opt,name=used_heap_MB" json:"used_heap_MB,omitempty"`
// * the maximum allowable size of the heap, in MB.
MaxHeap_MB *uint32 `protobuf:"varint,4,opt,name=max_heap_MB" json:"max_heap_MB,omitempty"`
// * Information on the load of individual regions.
RegionLoads []*RegionLoad `protobuf:"bytes,5,rep,name=region_loads" json:"region_loads,omitempty"`
// *
// Regionserver-level coprocessors, e.g., WALObserver implementations.
// Region-level coprocessors, on the other hand, are stored inside RegionLoad
// objects.
Coprocessors []*Coprocessor `protobuf:"bytes,6,rep,name=coprocessors" json:"coprocessors,omitempty"`
// *
// Time when incremental (non-total) counts began being calculated (e.g. number_of_requests)
// time is measured as the difference, measured in milliseconds, between the current time
// and midnight, January 1, 1970 UTC.
ReportStartTime *uint64 `protobuf:"varint,7,opt,name=report_start_time" json:"report_start_time,omitempty"`
// *
// Time when report was generated.
// time is measured as the difference, measured in milliseconds, between the current time
// and midnight, January 1, 1970 UTC.
ReportEndTime *uint64 `protobuf:"varint,8,opt,name=report_end_time" json:"report_end_time,omitempty"`
// *
// The port number that this region server is hosing an info server on.
InfoServerPort *uint32 `protobuf:"varint,9,opt,name=info_server_port" json:"info_server_port,omitempty"`
// *
// The replicationLoadSource for the replication Source status of this region server.
ReplLoadSource []*ReplicationLoadSource `protobuf:"bytes,10,rep,name=replLoadSource" json:"replLoadSource,omitempty"`
// *
// The replicationLoadSink for the replication Sink status of this region server.
ReplLoadSink *ReplicationLoadSink `protobuf:"bytes,11,opt,name=replLoadSink" json:"replLoadSink,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ServerLoad) Reset() { *m = ServerLoad{} }
func (m *ServerLoad) String() string { return proto1.CompactTextString(m) }
func (*ServerLoad) ProtoMessage() {}
func (m *ServerLoad) GetNumberOfRequests() uint32 {
if m != nil && m.NumberOfRequests != nil {
return *m.NumberOfRequests
}
return 0
}
func (m *ServerLoad) GetTotalNumberOfRequests() uint32 {
if m != nil && m.TotalNumberOfRequests != nil {
return *m.TotalNumberOfRequests
}
return 0
}
func (m *ServerLoad) GetUsedHeap_MB() uint32 {
if m != nil && m.UsedHeap_MB != nil {
return *m.UsedHeap_MB
}
return 0
}
func (m *ServerLoad) GetMaxHeap_MB() uint32 {
if m != nil && m.MaxHeap_MB != nil {
return *m.MaxHeap_MB
}
return 0
}
func (m *ServerLoad) GetRegionLoads() []*RegionLoad {
if m != nil {
return m.RegionLoads
}
return nil
}
func (m *ServerLoad) GetCoprocessors() []*Coprocessor {
if m != nil {
return m.Coprocessors
}
return nil
}
func (m *ServerLoad) GetReportStartTime() uint64 {
if m != nil && m.ReportStartTime != nil {
return *m.ReportStartTime
}
return 0
}
func (m *ServerLoad) GetReportEndTime() uint64 {
if m != nil && m.ReportEndTime != nil {
return *m.ReportEndTime
}
return 0
}
func (m *ServerLoad) GetInfoServerPort() uint32 {
if m != nil && m.InfoServerPort != nil {
return *m.InfoServerPort
}
return 0
}
func (m *ServerLoad) GetReplLoadSource() []*ReplicationLoadSource {
if m != nil {
return m.ReplLoadSource
}
return nil
}
func (m *ServerLoad) GetReplLoadSink() *ReplicationLoadSink {
if m != nil {
return m.ReplLoadSink
}
return nil
}
type LiveServerInfo struct {
Server *ServerName `protobuf:"bytes,1,req,name=server" json:"server,omitempty"`
ServerLoad *ServerLoad `protobuf:"bytes,2,req,name=server_load" json:"server_load,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *LiveServerInfo) Reset() { *m = LiveServerInfo{} }
func (m *LiveServerInfo) String() string { return proto1.CompactTextString(m) }
func (*LiveServerInfo) ProtoMessage() {}
func (m *LiveServerInfo) GetServer() *ServerName {
if m != nil {
return m.Server
}
return nil
}
func (m *LiveServerInfo) GetServerLoad() *ServerLoad {
if m != nil {
return m.ServerLoad
}
return nil
}
type ClusterStatus struct {
HbaseVersion *HBaseVersionFileContent `protobuf:"bytes,1,opt,name=hbase_version" json:"hbase_version,omitempty"`
LiveServers []*LiveServerInfo `protobuf:"bytes,2,rep,name=live_servers" json:"live_servers,omitempty"`
DeadServers []*ServerName `protobuf:"bytes,3,rep,name=dead_servers" json:"dead_servers,omitempty"`
RegionsInTransition []*RegionInTransition `protobuf:"bytes,4,rep,name=regions_in_transition" json:"regions_in_transition,omitempty"`
ClusterId *ClusterId `protobuf:"bytes,5,opt,name=cluster_id" json:"cluster_id,omitempty"`
MasterCoprocessors []*Coprocessor `protobuf:"bytes,6,rep,name=master_coprocessors" json:"master_coprocessors,omitempty"`
Master *ServerName `protobuf:"bytes,7,opt,name=master" json:"master,omitempty"`
BackupMasters []*ServerName `protobuf:"bytes,8,rep,name=backup_masters" json:"backup_masters,omitempty"`
BalancerOn *bool `protobuf:"varint,9,opt,name=balancer_on" json:"balancer_on,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ClusterStatus) Reset() { *m = ClusterStatus{} }
func (m *ClusterStatus) String() string { return proto1.CompactTextString(m) }
func (*ClusterStatus) ProtoMessage() {}
func (m *ClusterStatus) GetHbaseVersion() *HBaseVersionFileContent {
if m != nil {
return m.HbaseVersion
}
return nil
}
func (m *ClusterStatus) GetLiveServers() []*LiveServerInfo {
if m != nil {
return m.LiveServers
}
return nil
}
func (m *ClusterStatus) GetDeadServers() []*ServerName {
if m != nil {
return m.DeadServers
}
return nil
}
func (m *ClusterStatus) GetRegionsInTransition() []*RegionInTransition {
if m != nil {
return m.RegionsInTransition
}
return nil
}
func (m *ClusterStatus) GetClusterId() *ClusterId {
if m != nil {
return m.ClusterId
}
return nil
}
func (m *ClusterStatus) GetMasterCoprocessors() []*Coprocessor {
if m != nil {
return m.MasterCoprocessors
}
return nil
}
func (m *ClusterStatus) GetMaster() *ServerName {
if m != nil {
return m.Master
}
return nil
}
func (m *ClusterStatus) GetBackupMasters() []*ServerName {
if m != nil {
return m.BackupMasters
}
return nil
}
func (m *ClusterStatus) GetBalancerOn() bool {
if m != nil && m.BalancerOn != nil {
return *m.BalancerOn
}
return false
}
func init() {
proto1.RegisterEnum("proto.RegionState_State", RegionState_State_name, RegionState_State_value)
}

View file

@ -0,0 +1,228 @@
// Code generated by protoc-gen-go.
// source: Comparator.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type BitComparator_BitwiseOp int32
const (
BitComparator_AND BitComparator_BitwiseOp = 1
BitComparator_OR BitComparator_BitwiseOp = 2
BitComparator_XOR BitComparator_BitwiseOp = 3
)
var BitComparator_BitwiseOp_name = map[int32]string{
1: "AND",
2: "OR",
3: "XOR",
}
var BitComparator_BitwiseOp_value = map[string]int32{
"AND": 1,
"OR": 2,
"XOR": 3,
}
func (x BitComparator_BitwiseOp) Enum() *BitComparator_BitwiseOp {
p := new(BitComparator_BitwiseOp)
*p = x
return p
}
func (x BitComparator_BitwiseOp) String() string {
return proto1.EnumName(BitComparator_BitwiseOp_name, int32(x))
}
func (x *BitComparator_BitwiseOp) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(BitComparator_BitwiseOp_value, data, "BitComparator_BitwiseOp")
if err != nil {
return err
}
*x = BitComparator_BitwiseOp(value)
return nil
}
type Comparator struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
SerializedComparator []byte `protobuf:"bytes,2,opt,name=serialized_comparator" json:"serialized_comparator,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Comparator) Reset() { *m = Comparator{} }
func (m *Comparator) String() string { return proto1.CompactTextString(m) }
func (*Comparator) ProtoMessage() {}
func (m *Comparator) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *Comparator) GetSerializedComparator() []byte {
if m != nil {
return m.SerializedComparator
}
return nil
}
type ByteArrayComparable struct {
Value []byte `protobuf:"bytes,1,opt,name=value" json:"value,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ByteArrayComparable) Reset() { *m = ByteArrayComparable{} }
func (m *ByteArrayComparable) String() string { return proto1.CompactTextString(m) }
func (*ByteArrayComparable) ProtoMessage() {}
func (m *ByteArrayComparable) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
type BinaryComparator struct {
Comparable *ByteArrayComparable `protobuf:"bytes,1,req,name=comparable" json:"comparable,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *BinaryComparator) Reset() { *m = BinaryComparator{} }
func (m *BinaryComparator) String() string { return proto1.CompactTextString(m) }
func (*BinaryComparator) ProtoMessage() {}
func (m *BinaryComparator) GetComparable() *ByteArrayComparable {
if m != nil {
return m.Comparable
}
return nil
}
type LongComparator struct {
Comparable *ByteArrayComparable `protobuf:"bytes,1,req,name=comparable" json:"comparable,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *LongComparator) Reset() { *m = LongComparator{} }
func (m *LongComparator) String() string { return proto1.CompactTextString(m) }
func (*LongComparator) ProtoMessage() {}
func (m *LongComparator) GetComparable() *ByteArrayComparable {
if m != nil {
return m.Comparable
}
return nil
}
type BinaryPrefixComparator struct {
Comparable *ByteArrayComparable `protobuf:"bytes,1,req,name=comparable" json:"comparable,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *BinaryPrefixComparator) Reset() { *m = BinaryPrefixComparator{} }
func (m *BinaryPrefixComparator) String() string { return proto1.CompactTextString(m) }
func (*BinaryPrefixComparator) ProtoMessage() {}
func (m *BinaryPrefixComparator) GetComparable() *ByteArrayComparable {
if m != nil {
return m.Comparable
}
return nil
}
type BitComparator struct {
Comparable *ByteArrayComparable `protobuf:"bytes,1,req,name=comparable" json:"comparable,omitempty"`
BitwiseOp *BitComparator_BitwiseOp `protobuf:"varint,2,req,name=bitwise_op,enum=proto.BitComparator_BitwiseOp" json:"bitwise_op,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *BitComparator) Reset() { *m = BitComparator{} }
func (m *BitComparator) String() string { return proto1.CompactTextString(m) }
func (*BitComparator) ProtoMessage() {}
func (m *BitComparator) GetComparable() *ByteArrayComparable {
if m != nil {
return m.Comparable
}
return nil
}
func (m *BitComparator) GetBitwiseOp() BitComparator_BitwiseOp {
if m != nil && m.BitwiseOp != nil {
return *m.BitwiseOp
}
return BitComparator_AND
}
type NullComparator struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *NullComparator) Reset() { *m = NullComparator{} }
func (m *NullComparator) String() string { return proto1.CompactTextString(m) }
func (*NullComparator) ProtoMessage() {}
type RegexStringComparator struct {
Pattern *string `protobuf:"bytes,1,req,name=pattern" json:"pattern,omitempty"`
PatternFlags *int32 `protobuf:"varint,2,req,name=pattern_flags" json:"pattern_flags,omitempty"`
Charset *string `protobuf:"bytes,3,req,name=charset" json:"charset,omitempty"`
Engine *string `protobuf:"bytes,4,opt,name=engine" json:"engine,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegexStringComparator) Reset() { *m = RegexStringComparator{} }
func (m *RegexStringComparator) String() string { return proto1.CompactTextString(m) }
func (*RegexStringComparator) ProtoMessage() {}
func (m *RegexStringComparator) GetPattern() string {
if m != nil && m.Pattern != nil {
return *m.Pattern
}
return ""
}
func (m *RegexStringComparator) GetPatternFlags() int32 {
if m != nil && m.PatternFlags != nil {
return *m.PatternFlags
}
return 0
}
func (m *RegexStringComparator) GetCharset() string {
if m != nil && m.Charset != nil {
return *m.Charset
}
return ""
}
func (m *RegexStringComparator) GetEngine() string {
if m != nil && m.Engine != nil {
return *m.Engine
}
return ""
}
type SubstringComparator struct {
Substr *string `protobuf:"bytes,1,req,name=substr" json:"substr,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SubstringComparator) Reset() { *m = SubstringComparator{} }
func (m *SubstringComparator) String() string { return proto1.CompactTextString(m) }
func (*SubstringComparator) ProtoMessage() {}
func (m *SubstringComparator) GetSubstr() string {
if m != nil && m.Substr != nil {
return *m.Substr
}
return ""
}
func init() {
proto1.RegisterEnum("proto.BitComparator_BitwiseOp", BitComparator_BitwiseOp_name, BitComparator_BitwiseOp_value)
}

View file

@ -0,0 +1,63 @@
// Code generated by protoc-gen-go.
// source: Encryption.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type WrappedKey struct {
Algorithm *string `protobuf:"bytes,1,req,name=algorithm" json:"algorithm,omitempty"`
Length *uint32 `protobuf:"varint,2,req,name=length" json:"length,omitempty"`
Data []byte `protobuf:"bytes,3,req,name=data" json:"data,omitempty"`
Iv []byte `protobuf:"bytes,4,opt,name=iv" json:"iv,omitempty"`
Hash []byte `protobuf:"bytes,5,opt,name=hash" json:"hash,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *WrappedKey) Reset() { *m = WrappedKey{} }
func (m *WrappedKey) String() string { return proto1.CompactTextString(m) }
func (*WrappedKey) ProtoMessage() {}
func (m *WrappedKey) GetAlgorithm() string {
if m != nil && m.Algorithm != nil {
return *m.Algorithm
}
return ""
}
func (m *WrappedKey) GetLength() uint32 {
if m != nil && m.Length != nil {
return *m.Length
}
return 0
}
func (m *WrappedKey) GetData() []byte {
if m != nil {
return m.Data
}
return nil
}
func (m *WrappedKey) GetIv() []byte {
if m != nil {
return m.Iv
}
return nil
}
func (m *WrappedKey) GetHash() []byte {
if m != nil {
return m.Hash
}
return nil
}
func init() {
}

View file

@ -0,0 +1,130 @@
// Code generated by protoc-gen-go.
// source: ErrorHandling.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
// *
// Protobuf version of a java.lang.StackTraceElement
// so we can serialize exceptions.
type StackTraceElementMessage struct {
DeclaringClass *string `protobuf:"bytes,1,opt,name=declaring_class" json:"declaring_class,omitempty"`
MethodName *string `protobuf:"bytes,2,opt,name=method_name" json:"method_name,omitempty"`
FileName *string `protobuf:"bytes,3,opt,name=file_name" json:"file_name,omitempty"`
LineNumber *int32 `protobuf:"varint,4,opt,name=line_number" json:"line_number,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *StackTraceElementMessage) Reset() { *m = StackTraceElementMessage{} }
func (m *StackTraceElementMessage) String() string { return proto1.CompactTextString(m) }
func (*StackTraceElementMessage) ProtoMessage() {}
func (m *StackTraceElementMessage) GetDeclaringClass() string {
if m != nil && m.DeclaringClass != nil {
return *m.DeclaringClass
}
return ""
}
func (m *StackTraceElementMessage) GetMethodName() string {
if m != nil && m.MethodName != nil {
return *m.MethodName
}
return ""
}
func (m *StackTraceElementMessage) GetFileName() string {
if m != nil && m.FileName != nil {
return *m.FileName
}
return ""
}
func (m *StackTraceElementMessage) GetLineNumber() int32 {
if m != nil && m.LineNumber != nil {
return *m.LineNumber
}
return 0
}
// *
// Cause of a remote failure for a generic exception. Contains
// all the information for a generic exception as well as
// optional info about the error for generic info passing
// (which should be another protobuffed class).
type GenericExceptionMessage struct {
ClassName *string `protobuf:"bytes,1,opt,name=class_name" json:"class_name,omitempty"`
Message *string `protobuf:"bytes,2,opt,name=message" json:"message,omitempty"`
ErrorInfo []byte `protobuf:"bytes,3,opt,name=error_info" json:"error_info,omitempty"`
Trace []*StackTraceElementMessage `protobuf:"bytes,4,rep,name=trace" json:"trace,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GenericExceptionMessage) Reset() { *m = GenericExceptionMessage{} }
func (m *GenericExceptionMessage) String() string { return proto1.CompactTextString(m) }
func (*GenericExceptionMessage) ProtoMessage() {}
func (m *GenericExceptionMessage) GetClassName() string {
if m != nil && m.ClassName != nil {
return *m.ClassName
}
return ""
}
func (m *GenericExceptionMessage) GetMessage() string {
if m != nil && m.Message != nil {
return *m.Message
}
return ""
}
func (m *GenericExceptionMessage) GetErrorInfo() []byte {
if m != nil {
return m.ErrorInfo
}
return nil
}
func (m *GenericExceptionMessage) GetTrace() []*StackTraceElementMessage {
if m != nil {
return m.Trace
}
return nil
}
// *
// Exception sent across the wire when a remote task needs
// to notify other tasks that it failed and why
type ForeignExceptionMessage struct {
Source *string `protobuf:"bytes,1,opt,name=source" json:"source,omitempty"`
GenericException *GenericExceptionMessage `protobuf:"bytes,2,opt,name=generic_exception" json:"generic_exception,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ForeignExceptionMessage) Reset() { *m = ForeignExceptionMessage{} }
func (m *ForeignExceptionMessage) String() string { return proto1.CompactTextString(m) }
func (*ForeignExceptionMessage) ProtoMessage() {}
func (m *ForeignExceptionMessage) GetSource() string {
if m != nil && m.Source != nil {
return *m.Source
}
return ""
}
func (m *ForeignExceptionMessage) GetGenericException() *GenericExceptionMessage {
if m != nil {
return m.GenericException
}
return nil
}
func init() {
}

93
vendor/github.com/pingcap/go-hbase/proto/FS.pb.go generated vendored Normal file
View file

@ -0,0 +1,93 @@
// Code generated by protoc-gen-go.
// source: FS.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type Reference_Range int32
const (
Reference_TOP Reference_Range = 0
Reference_BOTTOM Reference_Range = 1
)
var Reference_Range_name = map[int32]string{
0: "TOP",
1: "BOTTOM",
}
var Reference_Range_value = map[string]int32{
"TOP": 0,
"BOTTOM": 1,
}
func (x Reference_Range) Enum() *Reference_Range {
p := new(Reference_Range)
*p = x
return p
}
func (x Reference_Range) String() string {
return proto1.EnumName(Reference_Range_name, int32(x))
}
func (x *Reference_Range) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(Reference_Range_value, data, "Reference_Range")
if err != nil {
return err
}
*x = Reference_Range(value)
return nil
}
// *
// The ${HBASE_ROOTDIR}/hbase.version file content
type HBaseVersionFileContent struct {
Version *string `protobuf:"bytes,1,req,name=version" json:"version,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *HBaseVersionFileContent) Reset() { *m = HBaseVersionFileContent{} }
func (m *HBaseVersionFileContent) String() string { return proto1.CompactTextString(m) }
func (*HBaseVersionFileContent) ProtoMessage() {}
func (m *HBaseVersionFileContent) GetVersion() string {
if m != nil && m.Version != nil {
return *m.Version
}
return ""
}
// *
// Reference file content used when we split an hfile under a region.
type Reference struct {
Splitkey []byte `protobuf:"bytes,1,req,name=splitkey" json:"splitkey,omitempty"`
Range *Reference_Range `protobuf:"varint,2,req,name=range,enum=proto.Reference_Range" json:"range,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Reference) Reset() { *m = Reference{} }
func (m *Reference) String() string { return proto1.CompactTextString(m) }
func (*Reference) ProtoMessage() {}
func (m *Reference) GetSplitkey() []byte {
if m != nil {
return m.Splitkey
}
return nil
}
func (m *Reference) GetRange() Reference_Range {
if m != nil && m.Range != nil {
return *m.Range
}
return Reference_TOP
}
func init() {
proto1.RegisterEnum("proto.Reference_Range", Reference_Range_name, Reference_Range_value)
}

609
vendor/github.com/pingcap/go-hbase/proto/Filter.pb.go generated vendored Normal file
View file

@ -0,0 +1,609 @@
// Code generated by protoc-gen-go.
// source: Filter.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type FilterList_Operator int32
const (
FilterList_MUST_PASS_ALL FilterList_Operator = 1
FilterList_MUST_PASS_ONE FilterList_Operator = 2
)
var FilterList_Operator_name = map[int32]string{
1: "MUST_PASS_ALL",
2: "MUST_PASS_ONE",
}
var FilterList_Operator_value = map[string]int32{
"MUST_PASS_ALL": 1,
"MUST_PASS_ONE": 2,
}
func (x FilterList_Operator) Enum() *FilterList_Operator {
p := new(FilterList_Operator)
*p = x
return p
}
func (x FilterList_Operator) String() string {
return proto1.EnumName(FilterList_Operator_name, int32(x))
}
func (x *FilterList_Operator) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(FilterList_Operator_value, data, "FilterList_Operator")
if err != nil {
return err
}
*x = FilterList_Operator(value)
return nil
}
type Filter struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
SerializedFilter []byte `protobuf:"bytes,2,opt,name=serialized_filter" json:"serialized_filter,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Filter) Reset() { *m = Filter{} }
func (m *Filter) String() string { return proto1.CompactTextString(m) }
func (*Filter) ProtoMessage() {}
func (m *Filter) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *Filter) GetSerializedFilter() []byte {
if m != nil {
return m.SerializedFilter
}
return nil
}
type ColumnCountGetFilter struct {
Limit *int32 `protobuf:"varint,1,req,name=limit" json:"limit,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ColumnCountGetFilter) Reset() { *m = ColumnCountGetFilter{} }
func (m *ColumnCountGetFilter) String() string { return proto1.CompactTextString(m) }
func (*ColumnCountGetFilter) ProtoMessage() {}
func (m *ColumnCountGetFilter) GetLimit() int32 {
if m != nil && m.Limit != nil {
return *m.Limit
}
return 0
}
type ColumnPaginationFilter struct {
Limit *int32 `protobuf:"varint,1,req,name=limit" json:"limit,omitempty"`
Offset *int32 `protobuf:"varint,2,opt,name=offset" json:"offset,omitempty"`
ColumnOffset []byte `protobuf:"bytes,3,opt,name=column_offset" json:"column_offset,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ColumnPaginationFilter) Reset() { *m = ColumnPaginationFilter{} }
func (m *ColumnPaginationFilter) String() string { return proto1.CompactTextString(m) }
func (*ColumnPaginationFilter) ProtoMessage() {}
func (m *ColumnPaginationFilter) GetLimit() int32 {
if m != nil && m.Limit != nil {
return *m.Limit
}
return 0
}
func (m *ColumnPaginationFilter) GetOffset() int32 {
if m != nil && m.Offset != nil {
return *m.Offset
}
return 0
}
func (m *ColumnPaginationFilter) GetColumnOffset() []byte {
if m != nil {
return m.ColumnOffset
}
return nil
}
type ColumnPrefixFilter struct {
Prefix []byte `protobuf:"bytes,1,req,name=prefix" json:"prefix,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ColumnPrefixFilter) Reset() { *m = ColumnPrefixFilter{} }
func (m *ColumnPrefixFilter) String() string { return proto1.CompactTextString(m) }
func (*ColumnPrefixFilter) ProtoMessage() {}
func (m *ColumnPrefixFilter) GetPrefix() []byte {
if m != nil {
return m.Prefix
}
return nil
}
type ColumnRangeFilter struct {
MinColumn []byte `protobuf:"bytes,1,opt,name=min_column" json:"min_column,omitempty"`
MinColumnInclusive *bool `protobuf:"varint,2,opt,name=min_column_inclusive" json:"min_column_inclusive,omitempty"`
MaxColumn []byte `protobuf:"bytes,3,opt,name=max_column" json:"max_column,omitempty"`
MaxColumnInclusive *bool `protobuf:"varint,4,opt,name=max_column_inclusive" json:"max_column_inclusive,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ColumnRangeFilter) Reset() { *m = ColumnRangeFilter{} }
func (m *ColumnRangeFilter) String() string { return proto1.CompactTextString(m) }
func (*ColumnRangeFilter) ProtoMessage() {}
func (m *ColumnRangeFilter) GetMinColumn() []byte {
if m != nil {
return m.MinColumn
}
return nil
}
func (m *ColumnRangeFilter) GetMinColumnInclusive() bool {
if m != nil && m.MinColumnInclusive != nil {
return *m.MinColumnInclusive
}
return false
}
func (m *ColumnRangeFilter) GetMaxColumn() []byte {
if m != nil {
return m.MaxColumn
}
return nil
}
func (m *ColumnRangeFilter) GetMaxColumnInclusive() bool {
if m != nil && m.MaxColumnInclusive != nil {
return *m.MaxColumnInclusive
}
return false
}
type CompareFilter struct {
CompareOp *CompareType `protobuf:"varint,1,req,name=compare_op,enum=proto.CompareType" json:"compare_op,omitempty"`
Comparator *Comparator `protobuf:"bytes,2,opt,name=comparator" json:"comparator,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CompareFilter) Reset() { *m = CompareFilter{} }
func (m *CompareFilter) String() string { return proto1.CompactTextString(m) }
func (*CompareFilter) ProtoMessage() {}
func (m *CompareFilter) GetCompareOp() CompareType {
if m != nil && m.CompareOp != nil {
return *m.CompareOp
}
return CompareType_LESS
}
func (m *CompareFilter) GetComparator() *Comparator {
if m != nil {
return m.Comparator
}
return nil
}
type DependentColumnFilter struct {
CompareFilter *CompareFilter `protobuf:"bytes,1,req,name=compare_filter" json:"compare_filter,omitempty"`
ColumnFamily []byte `protobuf:"bytes,2,opt,name=column_family" json:"column_family,omitempty"`
ColumnQualifier []byte `protobuf:"bytes,3,opt,name=column_qualifier" json:"column_qualifier,omitempty"`
DropDependentColumn *bool `protobuf:"varint,4,opt,name=drop_dependent_column" json:"drop_dependent_column,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *DependentColumnFilter) Reset() { *m = DependentColumnFilter{} }
func (m *DependentColumnFilter) String() string { return proto1.CompactTextString(m) }
func (*DependentColumnFilter) ProtoMessage() {}
func (m *DependentColumnFilter) GetCompareFilter() *CompareFilter {
if m != nil {
return m.CompareFilter
}
return nil
}
func (m *DependentColumnFilter) GetColumnFamily() []byte {
if m != nil {
return m.ColumnFamily
}
return nil
}
func (m *DependentColumnFilter) GetColumnQualifier() []byte {
if m != nil {
return m.ColumnQualifier
}
return nil
}
func (m *DependentColumnFilter) GetDropDependentColumn() bool {
if m != nil && m.DropDependentColumn != nil {
return *m.DropDependentColumn
}
return false
}
type FamilyFilter struct {
CompareFilter *CompareFilter `protobuf:"bytes,1,req,name=compare_filter" json:"compare_filter,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FamilyFilter) Reset() { *m = FamilyFilter{} }
func (m *FamilyFilter) String() string { return proto1.CompactTextString(m) }
func (*FamilyFilter) ProtoMessage() {}
func (m *FamilyFilter) GetCompareFilter() *CompareFilter {
if m != nil {
return m.CompareFilter
}
return nil
}
type FilterList struct {
Operator *FilterList_Operator `protobuf:"varint,1,req,name=operator,enum=proto.FilterList_Operator" json:"operator,omitempty"`
Filters []*Filter `protobuf:"bytes,2,rep,name=filters" json:"filters,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FilterList) Reset() { *m = FilterList{} }
func (m *FilterList) String() string { return proto1.CompactTextString(m) }
func (*FilterList) ProtoMessage() {}
func (m *FilterList) GetOperator() FilterList_Operator {
if m != nil && m.Operator != nil {
return *m.Operator
}
return FilterList_MUST_PASS_ALL
}
func (m *FilterList) GetFilters() []*Filter {
if m != nil {
return m.Filters
}
return nil
}
type FilterWrapper struct {
Filter *Filter `protobuf:"bytes,1,req,name=filter" json:"filter,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FilterWrapper) Reset() { *m = FilterWrapper{} }
func (m *FilterWrapper) String() string { return proto1.CompactTextString(m) }
func (*FilterWrapper) ProtoMessage() {}
func (m *FilterWrapper) GetFilter() *Filter {
if m != nil {
return m.Filter
}
return nil
}
type FirstKeyOnlyFilter struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *FirstKeyOnlyFilter) Reset() { *m = FirstKeyOnlyFilter{} }
func (m *FirstKeyOnlyFilter) String() string { return proto1.CompactTextString(m) }
func (*FirstKeyOnlyFilter) ProtoMessage() {}
type FirstKeyValueMatchingQualifiersFilter struct {
Qualifiers [][]byte `protobuf:"bytes,1,rep,name=qualifiers" json:"qualifiers,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FirstKeyValueMatchingQualifiersFilter) Reset() { *m = FirstKeyValueMatchingQualifiersFilter{} }
func (m *FirstKeyValueMatchingQualifiersFilter) String() string { return proto1.CompactTextString(m) }
func (*FirstKeyValueMatchingQualifiersFilter) ProtoMessage() {}
func (m *FirstKeyValueMatchingQualifiersFilter) GetQualifiers() [][]byte {
if m != nil {
return m.Qualifiers
}
return nil
}
type FuzzyRowFilter struct {
FuzzyKeysData []*BytesBytesPair `protobuf:"bytes,1,rep,name=fuzzy_keys_data" json:"fuzzy_keys_data,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FuzzyRowFilter) Reset() { *m = FuzzyRowFilter{} }
func (m *FuzzyRowFilter) String() string { return proto1.CompactTextString(m) }
func (*FuzzyRowFilter) ProtoMessage() {}
func (m *FuzzyRowFilter) GetFuzzyKeysData() []*BytesBytesPair {
if m != nil {
return m.FuzzyKeysData
}
return nil
}
type InclusiveStopFilter struct {
StopRowKey []byte `protobuf:"bytes,1,opt,name=stop_row_key" json:"stop_row_key,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *InclusiveStopFilter) Reset() { *m = InclusiveStopFilter{} }
func (m *InclusiveStopFilter) String() string { return proto1.CompactTextString(m) }
func (*InclusiveStopFilter) ProtoMessage() {}
func (m *InclusiveStopFilter) GetStopRowKey() []byte {
if m != nil {
return m.StopRowKey
}
return nil
}
type KeyOnlyFilter struct {
LenAsVal *bool `protobuf:"varint,1,req,name=len_as_val" json:"len_as_val,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *KeyOnlyFilter) Reset() { *m = KeyOnlyFilter{} }
func (m *KeyOnlyFilter) String() string { return proto1.CompactTextString(m) }
func (*KeyOnlyFilter) ProtoMessage() {}
func (m *KeyOnlyFilter) GetLenAsVal() bool {
if m != nil && m.LenAsVal != nil {
return *m.LenAsVal
}
return false
}
type MultipleColumnPrefixFilter struct {
SortedPrefixes [][]byte `protobuf:"bytes,1,rep,name=sorted_prefixes" json:"sorted_prefixes,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *MultipleColumnPrefixFilter) Reset() { *m = MultipleColumnPrefixFilter{} }
func (m *MultipleColumnPrefixFilter) String() string { return proto1.CompactTextString(m) }
func (*MultipleColumnPrefixFilter) ProtoMessage() {}
func (m *MultipleColumnPrefixFilter) GetSortedPrefixes() [][]byte {
if m != nil {
return m.SortedPrefixes
}
return nil
}
type PageFilter struct {
PageSize *int64 `protobuf:"varint,1,req,name=page_size" json:"page_size,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *PageFilter) Reset() { *m = PageFilter{} }
func (m *PageFilter) String() string { return proto1.CompactTextString(m) }
func (*PageFilter) ProtoMessage() {}
func (m *PageFilter) GetPageSize() int64 {
if m != nil && m.PageSize != nil {
return *m.PageSize
}
return 0
}
type PrefixFilter struct {
Prefix []byte `protobuf:"bytes,1,opt,name=prefix" json:"prefix,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *PrefixFilter) Reset() { *m = PrefixFilter{} }
func (m *PrefixFilter) String() string { return proto1.CompactTextString(m) }
func (*PrefixFilter) ProtoMessage() {}
func (m *PrefixFilter) GetPrefix() []byte {
if m != nil {
return m.Prefix
}
return nil
}
type QualifierFilter struct {
CompareFilter *CompareFilter `protobuf:"bytes,1,req,name=compare_filter" json:"compare_filter,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *QualifierFilter) Reset() { *m = QualifierFilter{} }
func (m *QualifierFilter) String() string { return proto1.CompactTextString(m) }
func (*QualifierFilter) ProtoMessage() {}
func (m *QualifierFilter) GetCompareFilter() *CompareFilter {
if m != nil {
return m.CompareFilter
}
return nil
}
type RandomRowFilter struct {
Chance *float32 `protobuf:"fixed32,1,req,name=chance" json:"chance,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RandomRowFilter) Reset() { *m = RandomRowFilter{} }
func (m *RandomRowFilter) String() string { return proto1.CompactTextString(m) }
func (*RandomRowFilter) ProtoMessage() {}
func (m *RandomRowFilter) GetChance() float32 {
if m != nil && m.Chance != nil {
return *m.Chance
}
return 0
}
type RowFilter struct {
CompareFilter *CompareFilter `protobuf:"bytes,1,req,name=compare_filter" json:"compare_filter,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RowFilter) Reset() { *m = RowFilter{} }
func (m *RowFilter) String() string { return proto1.CompactTextString(m) }
func (*RowFilter) ProtoMessage() {}
func (m *RowFilter) GetCompareFilter() *CompareFilter {
if m != nil {
return m.CompareFilter
}
return nil
}
type SingleColumnValueExcludeFilter struct {
SingleColumnValueFilter *SingleColumnValueFilter `protobuf:"bytes,1,req,name=single_column_value_filter" json:"single_column_value_filter,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SingleColumnValueExcludeFilter) Reset() { *m = SingleColumnValueExcludeFilter{} }
func (m *SingleColumnValueExcludeFilter) String() string { return proto1.CompactTextString(m) }
func (*SingleColumnValueExcludeFilter) ProtoMessage() {}
func (m *SingleColumnValueExcludeFilter) GetSingleColumnValueFilter() *SingleColumnValueFilter {
if m != nil {
return m.SingleColumnValueFilter
}
return nil
}
type SingleColumnValueFilter struct {
ColumnFamily []byte `protobuf:"bytes,1,opt,name=column_family" json:"column_family,omitempty"`
ColumnQualifier []byte `protobuf:"bytes,2,opt,name=column_qualifier" json:"column_qualifier,omitempty"`
CompareOp *CompareType `protobuf:"varint,3,req,name=compare_op,enum=proto.CompareType" json:"compare_op,omitempty"`
Comparator *Comparator `protobuf:"bytes,4,req,name=comparator" json:"comparator,omitempty"`
FilterIfMissing *bool `protobuf:"varint,5,opt,name=filter_if_missing" json:"filter_if_missing,omitempty"`
LatestVersionOnly *bool `protobuf:"varint,6,opt,name=latest_version_only" json:"latest_version_only,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SingleColumnValueFilter) Reset() { *m = SingleColumnValueFilter{} }
func (m *SingleColumnValueFilter) String() string { return proto1.CompactTextString(m) }
func (*SingleColumnValueFilter) ProtoMessage() {}
func (m *SingleColumnValueFilter) GetColumnFamily() []byte {
if m != nil {
return m.ColumnFamily
}
return nil
}
func (m *SingleColumnValueFilter) GetColumnQualifier() []byte {
if m != nil {
return m.ColumnQualifier
}
return nil
}
func (m *SingleColumnValueFilter) GetCompareOp() CompareType {
if m != nil && m.CompareOp != nil {
return *m.CompareOp
}
return CompareType_LESS
}
func (m *SingleColumnValueFilter) GetComparator() *Comparator {
if m != nil {
return m.Comparator
}
return nil
}
func (m *SingleColumnValueFilter) GetFilterIfMissing() bool {
if m != nil && m.FilterIfMissing != nil {
return *m.FilterIfMissing
}
return false
}
func (m *SingleColumnValueFilter) GetLatestVersionOnly() bool {
if m != nil && m.LatestVersionOnly != nil {
return *m.LatestVersionOnly
}
return false
}
type SkipFilter struct {
Filter *Filter `protobuf:"bytes,1,req,name=filter" json:"filter,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SkipFilter) Reset() { *m = SkipFilter{} }
func (m *SkipFilter) String() string { return proto1.CompactTextString(m) }
func (*SkipFilter) ProtoMessage() {}
func (m *SkipFilter) GetFilter() *Filter {
if m != nil {
return m.Filter
}
return nil
}
type TimestampsFilter struct {
Timestamps []int64 `protobuf:"varint,1,rep,packed,name=timestamps" json:"timestamps,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *TimestampsFilter) Reset() { *m = TimestampsFilter{} }
func (m *TimestampsFilter) String() string { return proto1.CompactTextString(m) }
func (*TimestampsFilter) ProtoMessage() {}
func (m *TimestampsFilter) GetTimestamps() []int64 {
if m != nil {
return m.Timestamps
}
return nil
}
type ValueFilter struct {
CompareFilter *CompareFilter `protobuf:"bytes,1,req,name=compare_filter" json:"compare_filter,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ValueFilter) Reset() { *m = ValueFilter{} }
func (m *ValueFilter) String() string { return proto1.CompactTextString(m) }
func (*ValueFilter) ProtoMessage() {}
func (m *ValueFilter) GetCompareFilter() *CompareFilter {
if m != nil {
return m.CompareFilter
}
return nil
}
type WhileMatchFilter struct {
Filter *Filter `protobuf:"bytes,1,req,name=filter" json:"filter,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *WhileMatchFilter) Reset() { *m = WhileMatchFilter{} }
func (m *WhileMatchFilter) String() string { return proto1.CompactTextString(m) }
func (*WhileMatchFilter) ProtoMessage() {}
func (m *WhileMatchFilter) GetFilter() *Filter {
if m != nil {
return m.Filter
}
return nil
}
type FilterAllFilter struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *FilterAllFilter) Reset() { *m = FilterAllFilter{} }
func (m *FilterAllFilter) String() string { return proto1.CompactTextString(m) }
func (*FilterAllFilter) ProtoMessage() {}
func init() {
proto1.RegisterEnum("proto.FilterList_Operator", FilterList_Operator_name, FilterList_Operator_value)
}

741
vendor/github.com/pingcap/go-hbase/proto/HBase.pb.go generated vendored Normal file
View file

@ -0,0 +1,741 @@
// Code generated by protoc-gen-go.
// source: HBase.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
// Comparison operators
type CompareType int32
const (
CompareType_LESS CompareType = 0
CompareType_LESS_OR_EQUAL CompareType = 1
CompareType_EQUAL CompareType = 2
CompareType_NOT_EQUAL CompareType = 3
CompareType_GREATER_OR_EQUAL CompareType = 4
CompareType_GREATER CompareType = 5
CompareType_NO_OP CompareType = 6
)
var CompareType_name = map[int32]string{
0: "LESS",
1: "LESS_OR_EQUAL",
2: "EQUAL",
3: "NOT_EQUAL",
4: "GREATER_OR_EQUAL",
5: "GREATER",
6: "NO_OP",
}
var CompareType_value = map[string]int32{
"LESS": 0,
"LESS_OR_EQUAL": 1,
"EQUAL": 2,
"NOT_EQUAL": 3,
"GREATER_OR_EQUAL": 4,
"GREATER": 5,
"NO_OP": 6,
}
func (x CompareType) Enum() *CompareType {
p := new(CompareType)
*p = x
return p
}
func (x CompareType) String() string {
return proto1.EnumName(CompareType_name, int32(x))
}
func (x *CompareType) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(CompareType_value, data, "CompareType")
if err != nil {
return err
}
*x = CompareType(value)
return nil
}
type RegionSpecifier_RegionSpecifierType int32
const (
// <tablename>,<startkey>,<regionId>.<encodedName>
RegionSpecifier_REGION_NAME RegionSpecifier_RegionSpecifierType = 1
// hash of <tablename>,<startkey>,<regionId>
RegionSpecifier_ENCODED_REGION_NAME RegionSpecifier_RegionSpecifierType = 2
)
var RegionSpecifier_RegionSpecifierType_name = map[int32]string{
1: "REGION_NAME",
2: "ENCODED_REGION_NAME",
}
var RegionSpecifier_RegionSpecifierType_value = map[string]int32{
"REGION_NAME": 1,
"ENCODED_REGION_NAME": 2,
}
func (x RegionSpecifier_RegionSpecifierType) Enum() *RegionSpecifier_RegionSpecifierType {
p := new(RegionSpecifier_RegionSpecifierType)
*p = x
return p
}
func (x RegionSpecifier_RegionSpecifierType) String() string {
return proto1.EnumName(RegionSpecifier_RegionSpecifierType_name, int32(x))
}
func (x *RegionSpecifier_RegionSpecifierType) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(RegionSpecifier_RegionSpecifierType_value, data, "RegionSpecifier_RegionSpecifierType")
if err != nil {
return err
}
*x = RegionSpecifier_RegionSpecifierType(value)
return nil
}
type SnapshotDescription_Type int32
const (
SnapshotDescription_DISABLED SnapshotDescription_Type = 0
SnapshotDescription_FLUSH SnapshotDescription_Type = 1
SnapshotDescription_SKIPFLUSH SnapshotDescription_Type = 2
)
var SnapshotDescription_Type_name = map[int32]string{
0: "DISABLED",
1: "FLUSH",
2: "SKIPFLUSH",
}
var SnapshotDescription_Type_value = map[string]int32{
"DISABLED": 0,
"FLUSH": 1,
"SKIPFLUSH": 2,
}
func (x SnapshotDescription_Type) Enum() *SnapshotDescription_Type {
p := new(SnapshotDescription_Type)
*p = x
return p
}
func (x SnapshotDescription_Type) String() string {
return proto1.EnumName(SnapshotDescription_Type_name, int32(x))
}
func (x *SnapshotDescription_Type) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(SnapshotDescription_Type_value, data, "SnapshotDescription_Type")
if err != nil {
return err
}
*x = SnapshotDescription_Type(value)
return nil
}
// *
// Table Name
type TableName struct {
Namespace []byte `protobuf:"bytes,1,req,name=namespace" json:"namespace,omitempty"`
Qualifier []byte `protobuf:"bytes,2,req,name=qualifier" json:"qualifier,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *TableName) Reset() { *m = TableName{} }
func (m *TableName) String() string { return proto1.CompactTextString(m) }
func (*TableName) ProtoMessage() {}
func (m *TableName) GetNamespace() []byte {
if m != nil {
return m.Namespace
}
return nil
}
func (m *TableName) GetQualifier() []byte {
if m != nil {
return m.Qualifier
}
return nil
}
// *
// Table Schema
// Inspired by the rest TableSchema
type TableSchema struct {
TableName *TableName `protobuf:"bytes,1,opt,name=table_name" json:"table_name,omitempty"`
Attributes []*BytesBytesPair `protobuf:"bytes,2,rep,name=attributes" json:"attributes,omitempty"`
ColumnFamilies []*ColumnFamilySchema `protobuf:"bytes,3,rep,name=column_families" json:"column_families,omitempty"`
Configuration []*NameStringPair `protobuf:"bytes,4,rep,name=configuration" json:"configuration,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *TableSchema) Reset() { *m = TableSchema{} }
func (m *TableSchema) String() string { return proto1.CompactTextString(m) }
func (*TableSchema) ProtoMessage() {}
func (m *TableSchema) GetTableName() *TableName {
if m != nil {
return m.TableName
}
return nil
}
func (m *TableSchema) GetAttributes() []*BytesBytesPair {
if m != nil {
return m.Attributes
}
return nil
}
func (m *TableSchema) GetColumnFamilies() []*ColumnFamilySchema {
if m != nil {
return m.ColumnFamilies
}
return nil
}
func (m *TableSchema) GetConfiguration() []*NameStringPair {
if m != nil {
return m.Configuration
}
return nil
}
// *
// Column Family Schema
// Inspired by the rest ColumSchemaMessage
type ColumnFamilySchema struct {
Name []byte `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Attributes []*BytesBytesPair `protobuf:"bytes,2,rep,name=attributes" json:"attributes,omitempty"`
Configuration []*NameStringPair `protobuf:"bytes,3,rep,name=configuration" json:"configuration,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ColumnFamilySchema) Reset() { *m = ColumnFamilySchema{} }
func (m *ColumnFamilySchema) String() string { return proto1.CompactTextString(m) }
func (*ColumnFamilySchema) ProtoMessage() {}
func (m *ColumnFamilySchema) GetName() []byte {
if m != nil {
return m.Name
}
return nil
}
func (m *ColumnFamilySchema) GetAttributes() []*BytesBytesPair {
if m != nil {
return m.Attributes
}
return nil
}
func (m *ColumnFamilySchema) GetConfiguration() []*NameStringPair {
if m != nil {
return m.Configuration
}
return nil
}
// *
// Protocol buffer version of HRegionInfo.
type RegionInfo struct {
RegionId *uint64 `protobuf:"varint,1,req,name=region_id" json:"region_id,omitempty"`
TableName *TableName `protobuf:"bytes,2,req,name=table_name" json:"table_name,omitempty"`
StartKey []byte `protobuf:"bytes,3,opt,name=start_key" json:"start_key,omitempty"`
EndKey []byte `protobuf:"bytes,4,opt,name=end_key" json:"end_key,omitempty"`
Offline *bool `protobuf:"varint,5,opt,name=offline" json:"offline,omitempty"`
Split *bool `protobuf:"varint,6,opt,name=split" json:"split,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionInfo) Reset() { *m = RegionInfo{} }
func (m *RegionInfo) String() string { return proto1.CompactTextString(m) }
func (*RegionInfo) ProtoMessage() {}
func (m *RegionInfo) GetRegionId() uint64 {
if m != nil && m.RegionId != nil {
return *m.RegionId
}
return 0
}
func (m *RegionInfo) GetTableName() *TableName {
if m != nil {
return m.TableName
}
return nil
}
func (m *RegionInfo) GetStartKey() []byte {
if m != nil {
return m.StartKey
}
return nil
}
func (m *RegionInfo) GetEndKey() []byte {
if m != nil {
return m.EndKey
}
return nil
}
func (m *RegionInfo) GetOffline() bool {
if m != nil && m.Offline != nil {
return *m.Offline
}
return false
}
func (m *RegionInfo) GetSplit() bool {
if m != nil && m.Split != nil {
return *m.Split
}
return false
}
// *
// Protocol buffer for favored nodes
type FavoredNodes struct {
FavoredNode []*ServerName `protobuf:"bytes,1,rep,name=favored_node" json:"favored_node,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FavoredNodes) Reset() { *m = FavoredNodes{} }
func (m *FavoredNodes) String() string { return proto1.CompactTextString(m) }
func (*FavoredNodes) ProtoMessage() {}
func (m *FavoredNodes) GetFavoredNode() []*ServerName {
if m != nil {
return m.FavoredNode
}
return nil
}
// *
// Container protocol buffer to specify a region.
// You can specify region by region name, or the hash
// of the region name, which is known as encoded
// region name.
type RegionSpecifier struct {
Type *RegionSpecifier_RegionSpecifierType `protobuf:"varint,1,req,name=type,enum=proto.RegionSpecifier_RegionSpecifierType" json:"type,omitempty"`
Value []byte `protobuf:"bytes,2,req,name=value" json:"value,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionSpecifier) Reset() { *m = RegionSpecifier{} }
func (m *RegionSpecifier) String() string { return proto1.CompactTextString(m) }
func (*RegionSpecifier) ProtoMessage() {}
func (m *RegionSpecifier) GetType() RegionSpecifier_RegionSpecifierType {
if m != nil && m.Type != nil {
return *m.Type
}
return RegionSpecifier_REGION_NAME
}
func (m *RegionSpecifier) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
// *
// A range of time. Both from and to are Java time
// stamp in milliseconds. If you don't specify a time
// range, it means all time. By default, if not
// specified, from = 0, and to = Long.MAX_VALUE
type TimeRange struct {
From *uint64 `protobuf:"varint,1,opt,name=from" json:"from,omitempty"`
To *uint64 `protobuf:"varint,2,opt,name=to" json:"to,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *TimeRange) Reset() { *m = TimeRange{} }
func (m *TimeRange) String() string { return proto1.CompactTextString(m) }
func (*TimeRange) ProtoMessage() {}
func (m *TimeRange) GetFrom() uint64 {
if m != nil && m.From != nil {
return *m.From
}
return 0
}
func (m *TimeRange) GetTo() uint64 {
if m != nil && m.To != nil {
return *m.To
}
return 0
}
// *
// Protocol buffer version of ServerName
type ServerName struct {
HostName *string `protobuf:"bytes,1,req,name=host_name" json:"host_name,omitempty"`
Port *uint32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"`
StartCode *uint64 `protobuf:"varint,3,opt,name=start_code" json:"start_code,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ServerName) Reset() { *m = ServerName{} }
func (m *ServerName) String() string { return proto1.CompactTextString(m) }
func (*ServerName) ProtoMessage() {}
func (m *ServerName) GetHostName() string {
if m != nil && m.HostName != nil {
return *m.HostName
}
return ""
}
func (m *ServerName) GetPort() uint32 {
if m != nil && m.Port != nil {
return *m.Port
}
return 0
}
func (m *ServerName) GetStartCode() uint64 {
if m != nil && m.StartCode != nil {
return *m.StartCode
}
return 0
}
type Coprocessor struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Coprocessor) Reset() { *m = Coprocessor{} }
func (m *Coprocessor) String() string { return proto1.CompactTextString(m) }
func (*Coprocessor) ProtoMessage() {}
func (m *Coprocessor) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
type NameStringPair struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Value *string `protobuf:"bytes,2,req,name=value" json:"value,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *NameStringPair) Reset() { *m = NameStringPair{} }
func (m *NameStringPair) String() string { return proto1.CompactTextString(m) }
func (*NameStringPair) ProtoMessage() {}
func (m *NameStringPair) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *NameStringPair) GetValue() string {
if m != nil && m.Value != nil {
return *m.Value
}
return ""
}
type NameBytesPair struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Value []byte `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *NameBytesPair) Reset() { *m = NameBytesPair{} }
func (m *NameBytesPair) String() string { return proto1.CompactTextString(m) }
func (*NameBytesPair) ProtoMessage() {}
func (m *NameBytesPair) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *NameBytesPair) GetValue() []byte {
if m != nil {
return m.Value
}
return nil
}
type BytesBytesPair struct {
First []byte `protobuf:"bytes,1,req,name=first" json:"first,omitempty"`
Second []byte `protobuf:"bytes,2,req,name=second" json:"second,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *BytesBytesPair) Reset() { *m = BytesBytesPair{} }
func (m *BytesBytesPair) String() string { return proto1.CompactTextString(m) }
func (*BytesBytesPair) ProtoMessage() {}
func (m *BytesBytesPair) GetFirst() []byte {
if m != nil {
return m.First
}
return nil
}
func (m *BytesBytesPair) GetSecond() []byte {
if m != nil {
return m.Second
}
return nil
}
type NameInt64Pair struct {
Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
Value *int64 `protobuf:"varint,2,opt,name=value" json:"value,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *NameInt64Pair) Reset() { *m = NameInt64Pair{} }
func (m *NameInt64Pair) String() string { return proto1.CompactTextString(m) }
func (*NameInt64Pair) ProtoMessage() {}
func (m *NameInt64Pair) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *NameInt64Pair) GetValue() int64 {
if m != nil && m.Value != nil {
return *m.Value
}
return 0
}
// *
// Description of the snapshot to take
type SnapshotDescription struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Table *string `protobuf:"bytes,2,opt,name=table" json:"table,omitempty"`
CreationTime *int64 `protobuf:"varint,3,opt,name=creation_time,def=0" json:"creation_time,omitempty"`
Type *SnapshotDescription_Type `protobuf:"varint,4,opt,name=type,enum=proto.SnapshotDescription_Type,def=1" json:"type,omitempty"`
Version *int32 `protobuf:"varint,5,opt,name=version" json:"version,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotDescription) Reset() { *m = SnapshotDescription{} }
func (m *SnapshotDescription) String() string { return proto1.CompactTextString(m) }
func (*SnapshotDescription) ProtoMessage() {}
const Default_SnapshotDescription_CreationTime int64 = 0
const Default_SnapshotDescription_Type SnapshotDescription_Type = SnapshotDescription_FLUSH
func (m *SnapshotDescription) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *SnapshotDescription) GetTable() string {
if m != nil && m.Table != nil {
return *m.Table
}
return ""
}
func (m *SnapshotDescription) GetCreationTime() int64 {
if m != nil && m.CreationTime != nil {
return *m.CreationTime
}
return Default_SnapshotDescription_CreationTime
}
func (m *SnapshotDescription) GetType() SnapshotDescription_Type {
if m != nil && m.Type != nil {
return *m.Type
}
return Default_SnapshotDescription_Type
}
func (m *SnapshotDescription) GetVersion() int32 {
if m != nil && m.Version != nil {
return *m.Version
}
return 0
}
// *
// Description of the distributed procedure to take
type ProcedureDescription struct {
Signature *string `protobuf:"bytes,1,req,name=signature" json:"signature,omitempty"`
Instance *string `protobuf:"bytes,2,opt,name=instance" json:"instance,omitempty"`
CreationTime *int64 `protobuf:"varint,3,opt,name=creation_time,def=0" json:"creation_time,omitempty"`
Configuration []*NameStringPair `protobuf:"bytes,4,rep,name=configuration" json:"configuration,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ProcedureDescription) Reset() { *m = ProcedureDescription{} }
func (m *ProcedureDescription) String() string { return proto1.CompactTextString(m) }
func (*ProcedureDescription) ProtoMessage() {}
const Default_ProcedureDescription_CreationTime int64 = 0
func (m *ProcedureDescription) GetSignature() string {
if m != nil && m.Signature != nil {
return *m.Signature
}
return ""
}
func (m *ProcedureDescription) GetInstance() string {
if m != nil && m.Instance != nil {
return *m.Instance
}
return ""
}
func (m *ProcedureDescription) GetCreationTime() int64 {
if m != nil && m.CreationTime != nil {
return *m.CreationTime
}
return Default_ProcedureDescription_CreationTime
}
func (m *ProcedureDescription) GetConfiguration() []*NameStringPair {
if m != nil {
return m.Configuration
}
return nil
}
type EmptyMsg struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *EmptyMsg) Reset() { *m = EmptyMsg{} }
func (m *EmptyMsg) String() string { return proto1.CompactTextString(m) }
func (*EmptyMsg) ProtoMessage() {}
type LongMsg struct {
LongMsg *int64 `protobuf:"varint,1,req,name=long_msg" json:"long_msg,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *LongMsg) Reset() { *m = LongMsg{} }
func (m *LongMsg) String() string { return proto1.CompactTextString(m) }
func (*LongMsg) ProtoMessage() {}
func (m *LongMsg) GetLongMsg() int64 {
if m != nil && m.LongMsg != nil {
return *m.LongMsg
}
return 0
}
type DoubleMsg struct {
DoubleMsg *float64 `protobuf:"fixed64,1,req,name=double_msg" json:"double_msg,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *DoubleMsg) Reset() { *m = DoubleMsg{} }
func (m *DoubleMsg) String() string { return proto1.CompactTextString(m) }
func (*DoubleMsg) ProtoMessage() {}
func (m *DoubleMsg) GetDoubleMsg() float64 {
if m != nil && m.DoubleMsg != nil {
return *m.DoubleMsg
}
return 0
}
type BigDecimalMsg struct {
BigdecimalMsg []byte `protobuf:"bytes,1,req,name=bigdecimal_msg" json:"bigdecimal_msg,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *BigDecimalMsg) Reset() { *m = BigDecimalMsg{} }
func (m *BigDecimalMsg) String() string { return proto1.CompactTextString(m) }
func (*BigDecimalMsg) ProtoMessage() {}
func (m *BigDecimalMsg) GetBigdecimalMsg() []byte {
if m != nil {
return m.BigdecimalMsg
}
return nil
}
type UUID struct {
LeastSigBits *uint64 `protobuf:"varint,1,req,name=least_sig_bits" json:"least_sig_bits,omitempty"`
MostSigBits *uint64 `protobuf:"varint,2,req,name=most_sig_bits" json:"most_sig_bits,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *UUID) Reset() { *m = UUID{} }
func (m *UUID) String() string { return proto1.CompactTextString(m) }
func (*UUID) ProtoMessage() {}
func (m *UUID) GetLeastSigBits() uint64 {
if m != nil && m.LeastSigBits != nil {
return *m.LeastSigBits
}
return 0
}
func (m *UUID) GetMostSigBits() uint64 {
if m != nil && m.MostSigBits != nil {
return *m.MostSigBits
}
return 0
}
type NamespaceDescriptor struct {
Name []byte `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Configuration []*NameStringPair `protobuf:"bytes,2,rep,name=configuration" json:"configuration,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *NamespaceDescriptor) Reset() { *m = NamespaceDescriptor{} }
func (m *NamespaceDescriptor) String() string { return proto1.CompactTextString(m) }
func (*NamespaceDescriptor) ProtoMessage() {}
func (m *NamespaceDescriptor) GetName() []byte {
if m != nil {
return m.Name
}
return nil
}
func (m *NamespaceDescriptor) GetConfiguration() []*NameStringPair {
if m != nil {
return m.Configuration
}
return nil
}
// *
// Description of the region server info
type RegionServerInfo struct {
InfoPort *int32 `protobuf:"varint,1,opt,name=infoPort" json:"infoPort,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionServerInfo) Reset() { *m = RegionServerInfo{} }
func (m *RegionServerInfo) String() string { return proto1.CompactTextString(m) }
func (*RegionServerInfo) ProtoMessage() {}
func (m *RegionServerInfo) GetInfoPort() int32 {
if m != nil && m.InfoPort != nil {
return *m.InfoPort
}
return 0
}
func init() {
proto1.RegisterEnum("proto.CompareType", CompareType_name, CompareType_value)
proto1.RegisterEnum("proto.RegionSpecifier_RegionSpecifierType", RegionSpecifier_RegionSpecifierType_name, RegionSpecifier_RegionSpecifierType_value)
proto1.RegisterEnum("proto.SnapshotDescription_Type", SnapshotDescription_Type_name, SnapshotDescription_Type_value)
}

145
vendor/github.com/pingcap/go-hbase/proto/HFile.pb.go generated vendored Normal file
View file

@ -0,0 +1,145 @@
// Code generated by protoc-gen-go.
// source: HFile.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
// Map of name/values
type FileInfoProto struct {
MapEntry []*BytesBytesPair `protobuf:"bytes,1,rep,name=map_entry" json:"map_entry,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FileInfoProto) Reset() { *m = FileInfoProto{} }
func (m *FileInfoProto) String() string { return proto1.CompactTextString(m) }
func (*FileInfoProto) ProtoMessage() {}
func (m *FileInfoProto) GetMapEntry() []*BytesBytesPair {
if m != nil {
return m.MapEntry
}
return nil
}
// HFile file trailer
type FileTrailerProto struct {
FileInfoOffset *uint64 `protobuf:"varint,1,opt,name=file_info_offset" json:"file_info_offset,omitempty"`
LoadOnOpenDataOffset *uint64 `protobuf:"varint,2,opt,name=load_on_open_data_offset" json:"load_on_open_data_offset,omitempty"`
UncompressedDataIndexSize *uint64 `protobuf:"varint,3,opt,name=uncompressed_data_index_size" json:"uncompressed_data_index_size,omitempty"`
TotalUncompressedBytes *uint64 `protobuf:"varint,4,opt,name=total_uncompressed_bytes" json:"total_uncompressed_bytes,omitempty"`
DataIndexCount *uint32 `protobuf:"varint,5,opt,name=data_index_count" json:"data_index_count,omitempty"`
MetaIndexCount *uint32 `protobuf:"varint,6,opt,name=meta_index_count" json:"meta_index_count,omitempty"`
EntryCount *uint64 `protobuf:"varint,7,opt,name=entry_count" json:"entry_count,omitempty"`
NumDataIndexLevels *uint32 `protobuf:"varint,8,opt,name=num_data_index_levels" json:"num_data_index_levels,omitempty"`
FirstDataBlockOffset *uint64 `protobuf:"varint,9,opt,name=first_data_block_offset" json:"first_data_block_offset,omitempty"`
LastDataBlockOffset *uint64 `protobuf:"varint,10,opt,name=last_data_block_offset" json:"last_data_block_offset,omitempty"`
ComparatorClassName *string `protobuf:"bytes,11,opt,name=comparator_class_name" json:"comparator_class_name,omitempty"`
CompressionCodec *uint32 `protobuf:"varint,12,opt,name=compression_codec" json:"compression_codec,omitempty"`
EncryptionKey []byte `protobuf:"bytes,13,opt,name=encryption_key" json:"encryption_key,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FileTrailerProto) Reset() { *m = FileTrailerProto{} }
func (m *FileTrailerProto) String() string { return proto1.CompactTextString(m) }
func (*FileTrailerProto) ProtoMessage() {}
func (m *FileTrailerProto) GetFileInfoOffset() uint64 {
if m != nil && m.FileInfoOffset != nil {
return *m.FileInfoOffset
}
return 0
}
func (m *FileTrailerProto) GetLoadOnOpenDataOffset() uint64 {
if m != nil && m.LoadOnOpenDataOffset != nil {
return *m.LoadOnOpenDataOffset
}
return 0
}
func (m *FileTrailerProto) GetUncompressedDataIndexSize() uint64 {
if m != nil && m.UncompressedDataIndexSize != nil {
return *m.UncompressedDataIndexSize
}
return 0
}
func (m *FileTrailerProto) GetTotalUncompressedBytes() uint64 {
if m != nil && m.TotalUncompressedBytes != nil {
return *m.TotalUncompressedBytes
}
return 0
}
func (m *FileTrailerProto) GetDataIndexCount() uint32 {
if m != nil && m.DataIndexCount != nil {
return *m.DataIndexCount
}
return 0
}
func (m *FileTrailerProto) GetMetaIndexCount() uint32 {
if m != nil && m.MetaIndexCount != nil {
return *m.MetaIndexCount
}
return 0
}
func (m *FileTrailerProto) GetEntryCount() uint64 {
if m != nil && m.EntryCount != nil {
return *m.EntryCount
}
return 0
}
func (m *FileTrailerProto) GetNumDataIndexLevels() uint32 {
if m != nil && m.NumDataIndexLevels != nil {
return *m.NumDataIndexLevels
}
return 0
}
func (m *FileTrailerProto) GetFirstDataBlockOffset() uint64 {
if m != nil && m.FirstDataBlockOffset != nil {
return *m.FirstDataBlockOffset
}
return 0
}
func (m *FileTrailerProto) GetLastDataBlockOffset() uint64 {
if m != nil && m.LastDataBlockOffset != nil {
return *m.LastDataBlockOffset
}
return 0
}
func (m *FileTrailerProto) GetComparatorClassName() string {
if m != nil && m.ComparatorClassName != nil {
return *m.ComparatorClassName
}
return ""
}
func (m *FileTrailerProto) GetCompressionCodec() uint32 {
if m != nil && m.CompressionCodec != nil {
return *m.CompressionCodec
}
return 0
}
func (m *FileTrailerProto) GetEncryptionKey() []byte {
if m != nil {
return m.EncryptionKey
}
return nil
}
func init() {
}

View file

@ -0,0 +1,31 @@
// Code generated by protoc-gen-go.
// source: LoadBalancer.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type LoadBalancerState struct {
BalancerOn *bool `protobuf:"varint,1,opt,name=balancer_on" json:"balancer_on,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *LoadBalancerState) Reset() { *m = LoadBalancerState{} }
func (m *LoadBalancerState) String() string { return proto1.CompactTextString(m) }
func (*LoadBalancerState) ProtoMessage() {}
func (m *LoadBalancerState) GetBalancerOn() bool {
if m != nil && m.BalancerOn != nil {
return *m.BalancerOn
}
return false
}
func init() {
}

View file

@ -0,0 +1,63 @@
// Code generated by protoc-gen-go.
// source: MapReduce.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type ScanMetrics struct {
Metrics []*NameInt64Pair `protobuf:"bytes,1,rep,name=metrics" json:"metrics,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ScanMetrics) Reset() { *m = ScanMetrics{} }
func (m *ScanMetrics) String() string { return proto1.CompactTextString(m) }
func (*ScanMetrics) ProtoMessage() {}
func (m *ScanMetrics) GetMetrics() []*NameInt64Pair {
if m != nil {
return m.Metrics
}
return nil
}
type TableSnapshotRegionSplit struct {
Locations []string `protobuf:"bytes,2,rep,name=locations" json:"locations,omitempty"`
Table *TableSchema `protobuf:"bytes,3,opt,name=table" json:"table,omitempty"`
Region *RegionInfo `protobuf:"bytes,4,opt,name=region" json:"region,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *TableSnapshotRegionSplit) Reset() { *m = TableSnapshotRegionSplit{} }
func (m *TableSnapshotRegionSplit) String() string { return proto1.CompactTextString(m) }
func (*TableSnapshotRegionSplit) ProtoMessage() {}
func (m *TableSnapshotRegionSplit) GetLocations() []string {
if m != nil {
return m.Locations
}
return nil
}
func (m *TableSnapshotRegionSplit) GetTable() *TableSchema {
if m != nil {
return m.Table
}
return nil
}
func (m *TableSnapshotRegionSplit) GetRegion() *RegionInfo {
if m != nil {
return m.Region
}
return nil
}
func init() {
}

1235
vendor/github.com/pingcap/go-hbase/proto/Master.pb.go generated vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,71 @@
// Code generated by protoc-gen-go.
// source: MultiRowMutation.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type MultiRowMutationProcessorRequest struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *MultiRowMutationProcessorRequest) Reset() { *m = MultiRowMutationProcessorRequest{} }
func (m *MultiRowMutationProcessorRequest) String() string { return proto1.CompactTextString(m) }
func (*MultiRowMutationProcessorRequest) ProtoMessage() {}
type MultiRowMutationProcessorResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *MultiRowMutationProcessorResponse) Reset() { *m = MultiRowMutationProcessorResponse{} }
func (m *MultiRowMutationProcessorResponse) String() string { return proto1.CompactTextString(m) }
func (*MultiRowMutationProcessorResponse) ProtoMessage() {}
type MutateRowsRequest struct {
MutationRequest []*MutationProto `protobuf:"bytes,1,rep,name=mutation_request" json:"mutation_request,omitempty"`
NonceGroup *uint64 `protobuf:"varint,2,opt,name=nonce_group" json:"nonce_group,omitempty"`
Nonce *uint64 `protobuf:"varint,3,opt,name=nonce" json:"nonce,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *MutateRowsRequest) Reset() { *m = MutateRowsRequest{} }
func (m *MutateRowsRequest) String() string { return proto1.CompactTextString(m) }
func (*MutateRowsRequest) ProtoMessage() {}
func (m *MutateRowsRequest) GetMutationRequest() []*MutationProto {
if m != nil {
return m.MutationRequest
}
return nil
}
func (m *MutateRowsRequest) GetNonceGroup() uint64 {
if m != nil && m.NonceGroup != nil {
return *m.NonceGroup
}
return 0
}
func (m *MutateRowsRequest) GetNonce() uint64 {
if m != nil && m.Nonce != nil {
return *m.Nonce
}
return 0
}
type MutateRowsResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *MutateRowsResponse) Reset() { *m = MutateRowsResponse{} }
func (m *MutateRowsResponse) String() string { return proto1.CompactTextString(m) }
func (*MutateRowsResponse) ProtoMessage() {}
func init() {
}

319
vendor/github.com/pingcap/go-hbase/proto/RPC.pb.go generated vendored Normal file
View file

@ -0,0 +1,319 @@
// Code generated by protoc-gen-go.
// source: RPC.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
// User Information proto. Included in ConnectionHeader on connection setup
type UserInformation struct {
EffectiveUser *string `protobuf:"bytes,1,req,name=effective_user" json:"effective_user,omitempty"`
RealUser *string `protobuf:"bytes,2,opt,name=real_user" json:"real_user,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *UserInformation) Reset() { *m = UserInformation{} }
func (m *UserInformation) String() string { return proto1.CompactTextString(m) }
func (*UserInformation) ProtoMessage() {}
func (m *UserInformation) GetEffectiveUser() string {
if m != nil && m.EffectiveUser != nil {
return *m.EffectiveUser
}
return ""
}
func (m *UserInformation) GetRealUser() string {
if m != nil && m.RealUser != nil {
return *m.RealUser
}
return ""
}
// Rpc client version info proto. Included in ConnectionHeader on connection setup
type VersionInfo struct {
Version *string `protobuf:"bytes,1,req,name=version" json:"version,omitempty"`
Url *string `protobuf:"bytes,2,req,name=url" json:"url,omitempty"`
Revision *string `protobuf:"bytes,3,req,name=revision" json:"revision,omitempty"`
User *string `protobuf:"bytes,4,req,name=user" json:"user,omitempty"`
Date *string `protobuf:"bytes,5,req,name=date" json:"date,omitempty"`
SrcChecksum *string `protobuf:"bytes,6,req,name=src_checksum" json:"src_checksum,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *VersionInfo) Reset() { *m = VersionInfo{} }
func (m *VersionInfo) String() string { return proto1.CompactTextString(m) }
func (*VersionInfo) ProtoMessage() {}
func (m *VersionInfo) GetVersion() string {
if m != nil && m.Version != nil {
return *m.Version
}
return ""
}
func (m *VersionInfo) GetUrl() string {
if m != nil && m.Url != nil {
return *m.Url
}
return ""
}
func (m *VersionInfo) GetRevision() string {
if m != nil && m.Revision != nil {
return *m.Revision
}
return ""
}
func (m *VersionInfo) GetUser() string {
if m != nil && m.User != nil {
return *m.User
}
return ""
}
func (m *VersionInfo) GetDate() string {
if m != nil && m.Date != nil {
return *m.Date
}
return ""
}
func (m *VersionInfo) GetSrcChecksum() string {
if m != nil && m.SrcChecksum != nil {
return *m.SrcChecksum
}
return ""
}
// This is sent on connection setup after the connection preamble is sent.
type ConnectionHeader struct {
UserInfo *UserInformation `protobuf:"bytes,1,opt,name=user_info" json:"user_info,omitempty"`
ServiceName *string `protobuf:"bytes,2,opt,name=service_name" json:"service_name,omitempty"`
// Cell block codec we will use sending over optional cell blocks. Server throws exception
// if cannot deal. Null means no codec'ing going on so we are pb all the time (SLOW!!!)
CellBlockCodecClass *string `protobuf:"bytes,3,opt,name=cell_block_codec_class" json:"cell_block_codec_class,omitempty"`
// Compressor we will use if cell block is compressed. Server will throw exception if not supported.
// Class must implement hadoop's CompressionCodec Interface. Can't compress if no codec.
CellBlockCompressorClass *string `protobuf:"bytes,4,opt,name=cell_block_compressor_class" json:"cell_block_compressor_class,omitempty"`
VersionInfo *VersionInfo `protobuf:"bytes,5,opt,name=version_info" json:"version_info,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ConnectionHeader) Reset() { *m = ConnectionHeader{} }
func (m *ConnectionHeader) String() string { return proto1.CompactTextString(m) }
func (*ConnectionHeader) ProtoMessage() {}
func (m *ConnectionHeader) GetUserInfo() *UserInformation {
if m != nil {
return m.UserInfo
}
return nil
}
func (m *ConnectionHeader) GetServiceName() string {
if m != nil && m.ServiceName != nil {
return *m.ServiceName
}
return ""
}
func (m *ConnectionHeader) GetCellBlockCodecClass() string {
if m != nil && m.CellBlockCodecClass != nil {
return *m.CellBlockCodecClass
}
return ""
}
func (m *ConnectionHeader) GetCellBlockCompressorClass() string {
if m != nil && m.CellBlockCompressorClass != nil {
return *m.CellBlockCompressorClass
}
return ""
}
func (m *ConnectionHeader) GetVersionInfo() *VersionInfo {
if m != nil {
return m.VersionInfo
}
return nil
}
// Optional Cell block Message. Included in client RequestHeader
type CellBlockMeta struct {
// Length of the following cell block. Could calculate it but convenient having it too hand.
Length *uint32 `protobuf:"varint,1,opt,name=length" json:"length,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CellBlockMeta) Reset() { *m = CellBlockMeta{} }
func (m *CellBlockMeta) String() string { return proto1.CompactTextString(m) }
func (*CellBlockMeta) ProtoMessage() {}
func (m *CellBlockMeta) GetLength() uint32 {
if m != nil && m.Length != nil {
return *m.Length
}
return 0
}
// At the RPC layer, this message is used to carry
// the server side exception to the RPC client.
type ExceptionResponse struct {
// Class name of the exception thrown from the server
ExceptionClassName *string `protobuf:"bytes,1,opt,name=exception_class_name" json:"exception_class_name,omitempty"`
// Exception stack trace from the server side
StackTrace *string `protobuf:"bytes,2,opt,name=stack_trace" json:"stack_trace,omitempty"`
// Optional hostname. Filled in for some exceptions such as region moved
// where exception gives clue on where the region may have moved.
Hostname *string `protobuf:"bytes,3,opt,name=hostname" json:"hostname,omitempty"`
Port *int32 `protobuf:"varint,4,opt,name=port" json:"port,omitempty"`
// Set if we are NOT to retry on receipt of this exception
DoNotRetry *bool `protobuf:"varint,5,opt,name=do_not_retry" json:"do_not_retry,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ExceptionResponse) Reset() { *m = ExceptionResponse{} }
func (m *ExceptionResponse) String() string { return proto1.CompactTextString(m) }
func (*ExceptionResponse) ProtoMessage() {}
func (m *ExceptionResponse) GetExceptionClassName() string {
if m != nil && m.ExceptionClassName != nil {
return *m.ExceptionClassName
}
return ""
}
func (m *ExceptionResponse) GetStackTrace() string {
if m != nil && m.StackTrace != nil {
return *m.StackTrace
}
return ""
}
func (m *ExceptionResponse) GetHostname() string {
if m != nil && m.Hostname != nil {
return *m.Hostname
}
return ""
}
func (m *ExceptionResponse) GetPort() int32 {
if m != nil && m.Port != nil {
return *m.Port
}
return 0
}
func (m *ExceptionResponse) GetDoNotRetry() bool {
if m != nil && m.DoNotRetry != nil {
return *m.DoNotRetry
}
return false
}
// Header sent making a request.
type RequestHeader struct {
// Monotonically increasing call_id to keep track of RPC requests and their response
CallId *uint32 `protobuf:"varint,1,opt,name=call_id" json:"call_id,omitempty"`
TraceInfo *RPCTInfo `protobuf:"bytes,2,opt,name=trace_info" json:"trace_info,omitempty"`
MethodName *string `protobuf:"bytes,3,opt,name=method_name" json:"method_name,omitempty"`
// If true, then a pb Message param follows.
RequestParam *bool `protobuf:"varint,4,opt,name=request_param" json:"request_param,omitempty"`
// If present, then an encoded data block follows.
CellBlockMeta *CellBlockMeta `protobuf:"bytes,5,opt,name=cell_block_meta" json:"cell_block_meta,omitempty"`
// 0 is NORMAL priority. 100 is HIGH. If no priority, treat it as NORMAL.
// See HConstants.
Priority *uint32 `protobuf:"varint,6,opt,name=priority" json:"priority,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RequestHeader) Reset() { *m = RequestHeader{} }
func (m *RequestHeader) String() string { return proto1.CompactTextString(m) }
func (*RequestHeader) ProtoMessage() {}
func (m *RequestHeader) GetCallId() uint32 {
if m != nil && m.CallId != nil {
return *m.CallId
}
return 0
}
func (m *RequestHeader) GetTraceInfo() *RPCTInfo {
if m != nil {
return m.TraceInfo
}
return nil
}
func (m *RequestHeader) GetMethodName() string {
if m != nil && m.MethodName != nil {
return *m.MethodName
}
return ""
}
func (m *RequestHeader) GetRequestParam() bool {
if m != nil && m.RequestParam != nil {
return *m.RequestParam
}
return false
}
func (m *RequestHeader) GetCellBlockMeta() *CellBlockMeta {
if m != nil {
return m.CellBlockMeta
}
return nil
}
func (m *RequestHeader) GetPriority() uint32 {
if m != nil && m.Priority != nil {
return *m.Priority
}
return 0
}
type ResponseHeader struct {
CallId *uint32 `protobuf:"varint,1,opt,name=call_id" json:"call_id,omitempty"`
// If present, then request threw an exception and no response message (else we presume one)
Exception *ExceptionResponse `protobuf:"bytes,2,opt,name=exception" json:"exception,omitempty"`
// If present, then an encoded data block follows.
CellBlockMeta *CellBlockMeta `protobuf:"bytes,3,opt,name=cell_block_meta" json:"cell_block_meta,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ResponseHeader) Reset() { *m = ResponseHeader{} }
func (m *ResponseHeader) String() string { return proto1.CompactTextString(m) }
func (*ResponseHeader) ProtoMessage() {}
func (m *ResponseHeader) GetCallId() uint32 {
if m != nil && m.CallId != nil {
return *m.CallId
}
return 0
}
func (m *ResponseHeader) GetException() *ExceptionResponse {
if m != nil {
return m.Exception
}
return nil
}
func (m *ResponseHeader) GetCellBlockMeta() *CellBlockMeta {
if m != nil {
return m.CellBlockMeta
}
return nil
}
func init() {
}

View file

@ -0,0 +1,310 @@
// Code generated by protoc-gen-go.
// source: RegionServerStatus.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type RegionStateTransition_TransitionCode int32
const (
RegionStateTransition_OPENED RegionStateTransition_TransitionCode = 0
RegionStateTransition_FAILED_OPEN RegionStateTransition_TransitionCode = 1
// * No failed_close, in which case region server will abort
RegionStateTransition_CLOSED RegionStateTransition_TransitionCode = 2
// * Ask master for ok to split/merge region(s)
RegionStateTransition_READY_TO_SPLIT RegionStateTransition_TransitionCode = 3
RegionStateTransition_READY_TO_MERGE RegionStateTransition_TransitionCode = 4
RegionStateTransition_SPLIT_PONR RegionStateTransition_TransitionCode = 5
RegionStateTransition_MERGE_PONR RegionStateTransition_TransitionCode = 6
RegionStateTransition_SPLIT RegionStateTransition_TransitionCode = 7
RegionStateTransition_MERGED RegionStateTransition_TransitionCode = 8
RegionStateTransition_SPLIT_REVERTED RegionStateTransition_TransitionCode = 9
RegionStateTransition_MERGE_REVERTED RegionStateTransition_TransitionCode = 10
)
var RegionStateTransition_TransitionCode_name = map[int32]string{
0: "OPENED",
1: "FAILED_OPEN",
2: "CLOSED",
3: "READY_TO_SPLIT",
4: "READY_TO_MERGE",
5: "SPLIT_PONR",
6: "MERGE_PONR",
7: "SPLIT",
8: "MERGED",
9: "SPLIT_REVERTED",
10: "MERGE_REVERTED",
}
var RegionStateTransition_TransitionCode_value = map[string]int32{
"OPENED": 0,
"FAILED_OPEN": 1,
"CLOSED": 2,
"READY_TO_SPLIT": 3,
"READY_TO_MERGE": 4,
"SPLIT_PONR": 5,
"MERGE_PONR": 6,
"SPLIT": 7,
"MERGED": 8,
"SPLIT_REVERTED": 9,
"MERGE_REVERTED": 10,
}
func (x RegionStateTransition_TransitionCode) Enum() *RegionStateTransition_TransitionCode {
p := new(RegionStateTransition_TransitionCode)
*p = x
return p
}
func (x RegionStateTransition_TransitionCode) String() string {
return proto1.EnumName(RegionStateTransition_TransitionCode_name, int32(x))
}
func (x *RegionStateTransition_TransitionCode) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(RegionStateTransition_TransitionCode_value, data, "RegionStateTransition_TransitionCode")
if err != nil {
return err
}
*x = RegionStateTransition_TransitionCode(value)
return nil
}
type RegionServerStartupRequest struct {
// * Port number this regionserver is up on
Port *uint32 `protobuf:"varint,1,req,name=port" json:"port,omitempty"`
// * This servers' startcode
ServerStartCode *uint64 `protobuf:"varint,2,req,name=server_start_code" json:"server_start_code,omitempty"`
// * Current time of the region server in ms
ServerCurrentTime *uint64 `protobuf:"varint,3,req,name=server_current_time" json:"server_current_time,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionServerStartupRequest) Reset() { *m = RegionServerStartupRequest{} }
func (m *RegionServerStartupRequest) String() string { return proto1.CompactTextString(m) }
func (*RegionServerStartupRequest) ProtoMessage() {}
func (m *RegionServerStartupRequest) GetPort() uint32 {
if m != nil && m.Port != nil {
return *m.Port
}
return 0
}
func (m *RegionServerStartupRequest) GetServerStartCode() uint64 {
if m != nil && m.ServerStartCode != nil {
return *m.ServerStartCode
}
return 0
}
func (m *RegionServerStartupRequest) GetServerCurrentTime() uint64 {
if m != nil && m.ServerCurrentTime != nil {
return *m.ServerCurrentTime
}
return 0
}
type RegionServerStartupResponse struct {
// *
// Configuration for the regionserver to use: e.g. filesystem,
// hbase rootdir, the hostname to use creating the RegionServer ServerName,
// etc
MapEntries []*NameStringPair `protobuf:"bytes,1,rep,name=map_entries" json:"map_entries,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionServerStartupResponse) Reset() { *m = RegionServerStartupResponse{} }
func (m *RegionServerStartupResponse) String() string { return proto1.CompactTextString(m) }
func (*RegionServerStartupResponse) ProtoMessage() {}
func (m *RegionServerStartupResponse) GetMapEntries() []*NameStringPair {
if m != nil {
return m.MapEntries
}
return nil
}
type RegionServerReportRequest struct {
Server *ServerName `protobuf:"bytes,1,req,name=server" json:"server,omitempty"`
// * load the server is under
Load *ServerLoad `protobuf:"bytes,2,opt,name=load" json:"load,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionServerReportRequest) Reset() { *m = RegionServerReportRequest{} }
func (m *RegionServerReportRequest) String() string { return proto1.CompactTextString(m) }
func (*RegionServerReportRequest) ProtoMessage() {}
func (m *RegionServerReportRequest) GetServer() *ServerName {
if m != nil {
return m.Server
}
return nil
}
func (m *RegionServerReportRequest) GetLoad() *ServerLoad {
if m != nil {
return m.Load
}
return nil
}
type RegionServerReportResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionServerReportResponse) Reset() { *m = RegionServerReportResponse{} }
func (m *RegionServerReportResponse) String() string { return proto1.CompactTextString(m) }
func (*RegionServerReportResponse) ProtoMessage() {}
type ReportRSFatalErrorRequest struct {
// * name of the server experiencing the error
Server *ServerName `protobuf:"bytes,1,req,name=server" json:"server,omitempty"`
// * informative text to expose in the master logs and UI
ErrorMessage *string `protobuf:"bytes,2,req,name=error_message" json:"error_message,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ReportRSFatalErrorRequest) Reset() { *m = ReportRSFatalErrorRequest{} }
func (m *ReportRSFatalErrorRequest) String() string { return proto1.CompactTextString(m) }
func (*ReportRSFatalErrorRequest) ProtoMessage() {}
func (m *ReportRSFatalErrorRequest) GetServer() *ServerName {
if m != nil {
return m.Server
}
return nil
}
func (m *ReportRSFatalErrorRequest) GetErrorMessage() string {
if m != nil && m.ErrorMessage != nil {
return *m.ErrorMessage
}
return ""
}
type ReportRSFatalErrorResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *ReportRSFatalErrorResponse) Reset() { *m = ReportRSFatalErrorResponse{} }
func (m *ReportRSFatalErrorResponse) String() string { return proto1.CompactTextString(m) }
func (*ReportRSFatalErrorResponse) ProtoMessage() {}
type GetLastFlushedSequenceIdRequest struct {
// * region name
RegionName []byte `protobuf:"bytes,1,req,name=region_name" json:"region_name,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetLastFlushedSequenceIdRequest) Reset() { *m = GetLastFlushedSequenceIdRequest{} }
func (m *GetLastFlushedSequenceIdRequest) String() string { return proto1.CompactTextString(m) }
func (*GetLastFlushedSequenceIdRequest) ProtoMessage() {}
func (m *GetLastFlushedSequenceIdRequest) GetRegionName() []byte {
if m != nil {
return m.RegionName
}
return nil
}
type GetLastFlushedSequenceIdResponse struct {
// * the last HLog sequence id flushed from MemStore to HFile for the region
LastFlushedSequenceId *uint64 `protobuf:"varint,1,req,name=last_flushed_sequence_id" json:"last_flushed_sequence_id,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetLastFlushedSequenceIdResponse) Reset() { *m = GetLastFlushedSequenceIdResponse{} }
func (m *GetLastFlushedSequenceIdResponse) String() string { return proto1.CompactTextString(m) }
func (*GetLastFlushedSequenceIdResponse) ProtoMessage() {}
func (m *GetLastFlushedSequenceIdResponse) GetLastFlushedSequenceId() uint64 {
if m != nil && m.LastFlushedSequenceId != nil {
return *m.LastFlushedSequenceId
}
return 0
}
type RegionStateTransition struct {
TransitionCode *RegionStateTransition_TransitionCode `protobuf:"varint,1,req,name=transition_code,enum=proto.RegionStateTransition_TransitionCode" json:"transition_code,omitempty"`
// * Mutliple regions are involved during merging/splitting
RegionInfo []*RegionInfo `protobuf:"bytes,2,rep,name=region_info" json:"region_info,omitempty"`
// * For newly opened region, the open seq num is needed
OpenSeqNum *uint64 `protobuf:"varint,3,opt,name=open_seq_num" json:"open_seq_num,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionStateTransition) Reset() { *m = RegionStateTransition{} }
func (m *RegionStateTransition) String() string { return proto1.CompactTextString(m) }
func (*RegionStateTransition) ProtoMessage() {}
func (m *RegionStateTransition) GetTransitionCode() RegionStateTransition_TransitionCode {
if m != nil && m.TransitionCode != nil {
return *m.TransitionCode
}
return RegionStateTransition_OPENED
}
func (m *RegionStateTransition) GetRegionInfo() []*RegionInfo {
if m != nil {
return m.RegionInfo
}
return nil
}
func (m *RegionStateTransition) GetOpenSeqNum() uint64 {
if m != nil && m.OpenSeqNum != nil {
return *m.OpenSeqNum
}
return 0
}
type ReportRegionStateTransitionRequest struct {
// * This region server's server name
Server *ServerName `protobuf:"bytes,1,req,name=server" json:"server,omitempty"`
Transition []*RegionStateTransition `protobuf:"bytes,2,rep,name=transition" json:"transition,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ReportRegionStateTransitionRequest) Reset() { *m = ReportRegionStateTransitionRequest{} }
func (m *ReportRegionStateTransitionRequest) String() string { return proto1.CompactTextString(m) }
func (*ReportRegionStateTransitionRequest) ProtoMessage() {}
func (m *ReportRegionStateTransitionRequest) GetServer() *ServerName {
if m != nil {
return m.Server
}
return nil
}
func (m *ReportRegionStateTransitionRequest) GetTransition() []*RegionStateTransition {
if m != nil {
return m.Transition
}
return nil
}
type ReportRegionStateTransitionResponse struct {
// * Error message if failed to update the region state
ErrorMessage *string `protobuf:"bytes,1,opt,name=error_message" json:"error_message,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ReportRegionStateTransitionResponse) Reset() { *m = ReportRegionStateTransitionResponse{} }
func (m *ReportRegionStateTransitionResponse) String() string { return proto1.CompactTextString(m) }
func (*ReportRegionStateTransitionResponse) ProtoMessage() {}
func (m *ReportRegionStateTransitionResponse) GetErrorMessage() string {
if m != nil && m.ErrorMessage != nil {
return *m.ErrorMessage
}
return ""
}
func init() {
proto1.RegisterEnum("proto.RegionStateTransition_TransitionCode", RegionStateTransition_TransitionCode_name, RegionStateTransition_TransitionCode_value)
}

View file

@ -0,0 +1,79 @@
// Code generated by protoc-gen-go.
// source: RowProcessor.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type ProcessRequest struct {
RowProcessorClassName *string `protobuf:"bytes,1,req,name=row_processor_class_name" json:"row_processor_class_name,omitempty"`
RowProcessorInitializerMessageName *string `protobuf:"bytes,2,opt,name=row_processor_initializer_message_name" json:"row_processor_initializer_message_name,omitempty"`
RowProcessorInitializerMessage []byte `protobuf:"bytes,3,opt,name=row_processor_initializer_message" json:"row_processor_initializer_message,omitempty"`
NonceGroup *uint64 `protobuf:"varint,4,opt,name=nonce_group" json:"nonce_group,omitempty"`
Nonce *uint64 `protobuf:"varint,5,opt,name=nonce" json:"nonce,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ProcessRequest) Reset() { *m = ProcessRequest{} }
func (m *ProcessRequest) String() string { return proto1.CompactTextString(m) }
func (*ProcessRequest) ProtoMessage() {}
func (m *ProcessRequest) GetRowProcessorClassName() string {
if m != nil && m.RowProcessorClassName != nil {
return *m.RowProcessorClassName
}
return ""
}
func (m *ProcessRequest) GetRowProcessorInitializerMessageName() string {
if m != nil && m.RowProcessorInitializerMessageName != nil {
return *m.RowProcessorInitializerMessageName
}
return ""
}
func (m *ProcessRequest) GetRowProcessorInitializerMessage() []byte {
if m != nil {
return m.RowProcessorInitializerMessage
}
return nil
}
func (m *ProcessRequest) GetNonceGroup() uint64 {
if m != nil && m.NonceGroup != nil {
return *m.NonceGroup
}
return 0
}
func (m *ProcessRequest) GetNonce() uint64 {
if m != nil && m.Nonce != nil {
return *m.Nonce
}
return 0
}
type ProcessResponse struct {
RowProcessorResult []byte `protobuf:"bytes,1,req,name=row_processor_result" json:"row_processor_result,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ProcessResponse) Reset() { *m = ProcessResponse{} }
func (m *ProcessResponse) String() string { return proto1.CompactTextString(m) }
func (*ProcessResponse) ProtoMessage() {}
func (m *ProcessResponse) GetRowProcessorResult() []byte {
if m != nil {
return m.RowProcessorResult
}
return nil
}
func init() {
}

View file

@ -0,0 +1,167 @@
// Code generated by protoc-gen-go.
// source: SecureBulkLoad.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type SecureBulkLoadHFilesRequest struct {
FamilyPath []*BulkLoadHFileRequest_FamilyPath `protobuf:"bytes,1,rep,name=family_path" json:"family_path,omitempty"`
AssignSeqNum *bool `protobuf:"varint,2,opt,name=assign_seq_num" json:"assign_seq_num,omitempty"`
FsToken *DelegationToken `protobuf:"bytes,3,req,name=fs_token" json:"fs_token,omitempty"`
BulkToken *string `protobuf:"bytes,4,req,name=bulk_token" json:"bulk_token,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SecureBulkLoadHFilesRequest) Reset() { *m = SecureBulkLoadHFilesRequest{} }
func (m *SecureBulkLoadHFilesRequest) String() string { return proto1.CompactTextString(m) }
func (*SecureBulkLoadHFilesRequest) ProtoMessage() {}
func (m *SecureBulkLoadHFilesRequest) GetFamilyPath() []*BulkLoadHFileRequest_FamilyPath {
if m != nil {
return m.FamilyPath
}
return nil
}
func (m *SecureBulkLoadHFilesRequest) GetAssignSeqNum() bool {
if m != nil && m.AssignSeqNum != nil {
return *m.AssignSeqNum
}
return false
}
func (m *SecureBulkLoadHFilesRequest) GetFsToken() *DelegationToken {
if m != nil {
return m.FsToken
}
return nil
}
func (m *SecureBulkLoadHFilesRequest) GetBulkToken() string {
if m != nil && m.BulkToken != nil {
return *m.BulkToken
}
return ""
}
type SecureBulkLoadHFilesResponse struct {
Loaded *bool `protobuf:"varint,1,req,name=loaded" json:"loaded,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SecureBulkLoadHFilesResponse) Reset() { *m = SecureBulkLoadHFilesResponse{} }
func (m *SecureBulkLoadHFilesResponse) String() string { return proto1.CompactTextString(m) }
func (*SecureBulkLoadHFilesResponse) ProtoMessage() {}
func (m *SecureBulkLoadHFilesResponse) GetLoaded() bool {
if m != nil && m.Loaded != nil {
return *m.Loaded
}
return false
}
type DelegationToken struct {
Identifier []byte `protobuf:"bytes,1,opt,name=identifier" json:"identifier,omitempty"`
Password []byte `protobuf:"bytes,2,opt,name=password" json:"password,omitempty"`
Kind *string `protobuf:"bytes,3,opt,name=kind" json:"kind,omitempty"`
Service *string `protobuf:"bytes,4,opt,name=service" json:"service,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *DelegationToken) Reset() { *m = DelegationToken{} }
func (m *DelegationToken) String() string { return proto1.CompactTextString(m) }
func (*DelegationToken) ProtoMessage() {}
func (m *DelegationToken) GetIdentifier() []byte {
if m != nil {
return m.Identifier
}
return nil
}
func (m *DelegationToken) GetPassword() []byte {
if m != nil {
return m.Password
}
return nil
}
func (m *DelegationToken) GetKind() string {
if m != nil && m.Kind != nil {
return *m.Kind
}
return ""
}
func (m *DelegationToken) GetService() string {
if m != nil && m.Service != nil {
return *m.Service
}
return ""
}
type PrepareBulkLoadRequest struct {
TableName *TableName `protobuf:"bytes,1,req,name=table_name" json:"table_name,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *PrepareBulkLoadRequest) Reset() { *m = PrepareBulkLoadRequest{} }
func (m *PrepareBulkLoadRequest) String() string { return proto1.CompactTextString(m) }
func (*PrepareBulkLoadRequest) ProtoMessage() {}
func (m *PrepareBulkLoadRequest) GetTableName() *TableName {
if m != nil {
return m.TableName
}
return nil
}
type PrepareBulkLoadResponse struct {
BulkToken *string `protobuf:"bytes,1,req,name=bulk_token" json:"bulk_token,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *PrepareBulkLoadResponse) Reset() { *m = PrepareBulkLoadResponse{} }
func (m *PrepareBulkLoadResponse) String() string { return proto1.CompactTextString(m) }
func (*PrepareBulkLoadResponse) ProtoMessage() {}
func (m *PrepareBulkLoadResponse) GetBulkToken() string {
if m != nil && m.BulkToken != nil {
return *m.BulkToken
}
return ""
}
type CleanupBulkLoadRequest struct {
BulkToken *string `protobuf:"bytes,1,req,name=bulk_token" json:"bulk_token,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CleanupBulkLoadRequest) Reset() { *m = CleanupBulkLoadRequest{} }
func (m *CleanupBulkLoadRequest) String() string { return proto1.CompactTextString(m) }
func (*CleanupBulkLoadRequest) ProtoMessage() {}
func (m *CleanupBulkLoadRequest) GetBulkToken() string {
if m != nil && m.BulkToken != nil {
return *m.BulkToken
}
return ""
}
type CleanupBulkLoadResponse struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *CleanupBulkLoadResponse) Reset() { *m = CleanupBulkLoadResponse{} }
func (m *CleanupBulkLoadResponse) String() string { return proto1.CompactTextString(m) }
func (*CleanupBulkLoadResponse) ProtoMessage() {}
func init() {
}

202
vendor/github.com/pingcap/go-hbase/proto/Snapshot.pb.go generated vendored Normal file
View file

@ -0,0 +1,202 @@
// Code generated by protoc-gen-go.
// source: Snapshot.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type SnapshotFileInfo_Type int32
const (
SnapshotFileInfo_HFILE SnapshotFileInfo_Type = 1
SnapshotFileInfo_WAL SnapshotFileInfo_Type = 2
)
var SnapshotFileInfo_Type_name = map[int32]string{
1: "HFILE",
2: "WAL",
}
var SnapshotFileInfo_Type_value = map[string]int32{
"HFILE": 1,
"WAL": 2,
}
func (x SnapshotFileInfo_Type) Enum() *SnapshotFileInfo_Type {
p := new(SnapshotFileInfo_Type)
*p = x
return p
}
func (x SnapshotFileInfo_Type) String() string {
return proto1.EnumName(SnapshotFileInfo_Type_name, int32(x))
}
func (x *SnapshotFileInfo_Type) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(SnapshotFileInfo_Type_value, data, "SnapshotFileInfo_Type")
if err != nil {
return err
}
*x = SnapshotFileInfo_Type(value)
return nil
}
type SnapshotFileInfo struct {
Type *SnapshotFileInfo_Type `protobuf:"varint,1,req,name=type,enum=proto.SnapshotFileInfo_Type" json:"type,omitempty"`
Hfile *string `protobuf:"bytes,3,opt,name=hfile" json:"hfile,omitempty"`
WalServer *string `protobuf:"bytes,4,opt,name=wal_server" json:"wal_server,omitempty"`
WalName *string `protobuf:"bytes,5,opt,name=wal_name" json:"wal_name,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotFileInfo) Reset() { *m = SnapshotFileInfo{} }
func (m *SnapshotFileInfo) String() string { return proto1.CompactTextString(m) }
func (*SnapshotFileInfo) ProtoMessage() {}
func (m *SnapshotFileInfo) GetType() SnapshotFileInfo_Type {
if m != nil && m.Type != nil {
return *m.Type
}
return SnapshotFileInfo_HFILE
}
func (m *SnapshotFileInfo) GetHfile() string {
if m != nil && m.Hfile != nil {
return *m.Hfile
}
return ""
}
func (m *SnapshotFileInfo) GetWalServer() string {
if m != nil && m.WalServer != nil {
return *m.WalServer
}
return ""
}
func (m *SnapshotFileInfo) GetWalName() string {
if m != nil && m.WalName != nil {
return *m.WalName
}
return ""
}
type SnapshotRegionManifest struct {
Version *int32 `protobuf:"varint,1,opt,name=version" json:"version,omitempty"`
RegionInfo *RegionInfo `protobuf:"bytes,2,req,name=region_info" json:"region_info,omitempty"`
FamilyFiles []*SnapshotRegionManifest_FamilyFiles `protobuf:"bytes,3,rep,name=family_files" json:"family_files,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotRegionManifest) Reset() { *m = SnapshotRegionManifest{} }
func (m *SnapshotRegionManifest) String() string { return proto1.CompactTextString(m) }
func (*SnapshotRegionManifest) ProtoMessage() {}
func (m *SnapshotRegionManifest) GetVersion() int32 {
if m != nil && m.Version != nil {
return *m.Version
}
return 0
}
func (m *SnapshotRegionManifest) GetRegionInfo() *RegionInfo {
if m != nil {
return m.RegionInfo
}
return nil
}
func (m *SnapshotRegionManifest) GetFamilyFiles() []*SnapshotRegionManifest_FamilyFiles {
if m != nil {
return m.FamilyFiles
}
return nil
}
type SnapshotRegionManifest_StoreFile struct {
Name *string `protobuf:"bytes,1,req,name=name" json:"name,omitempty"`
Reference *Reference `protobuf:"bytes,2,opt,name=reference" json:"reference,omitempty"`
// TODO: Add checksums or other fields to verify the file
FileSize *uint64 `protobuf:"varint,3,opt,name=file_size" json:"file_size,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotRegionManifest_StoreFile) Reset() { *m = SnapshotRegionManifest_StoreFile{} }
func (m *SnapshotRegionManifest_StoreFile) String() string { return proto1.CompactTextString(m) }
func (*SnapshotRegionManifest_StoreFile) ProtoMessage() {}
func (m *SnapshotRegionManifest_StoreFile) GetName() string {
if m != nil && m.Name != nil {
return *m.Name
}
return ""
}
func (m *SnapshotRegionManifest_StoreFile) GetReference() *Reference {
if m != nil {
return m.Reference
}
return nil
}
func (m *SnapshotRegionManifest_StoreFile) GetFileSize() uint64 {
if m != nil && m.FileSize != nil {
return *m.FileSize
}
return 0
}
type SnapshotRegionManifest_FamilyFiles struct {
FamilyName []byte `protobuf:"bytes,1,req,name=family_name" json:"family_name,omitempty"`
StoreFiles []*SnapshotRegionManifest_StoreFile `protobuf:"bytes,2,rep,name=store_files" json:"store_files,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotRegionManifest_FamilyFiles) Reset() { *m = SnapshotRegionManifest_FamilyFiles{} }
func (m *SnapshotRegionManifest_FamilyFiles) String() string { return proto1.CompactTextString(m) }
func (*SnapshotRegionManifest_FamilyFiles) ProtoMessage() {}
func (m *SnapshotRegionManifest_FamilyFiles) GetFamilyName() []byte {
if m != nil {
return m.FamilyName
}
return nil
}
func (m *SnapshotRegionManifest_FamilyFiles) GetStoreFiles() []*SnapshotRegionManifest_StoreFile {
if m != nil {
return m.StoreFiles
}
return nil
}
type SnapshotDataManifest struct {
TableSchema *TableSchema `protobuf:"bytes,1,req,name=table_schema" json:"table_schema,omitempty"`
RegionManifests []*SnapshotRegionManifest `protobuf:"bytes,2,rep,name=region_manifests" json:"region_manifests,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SnapshotDataManifest) Reset() { *m = SnapshotDataManifest{} }
func (m *SnapshotDataManifest) String() string { return proto1.CompactTextString(m) }
func (*SnapshotDataManifest) ProtoMessage() {}
func (m *SnapshotDataManifest) GetTableSchema() *TableSchema {
if m != nil {
return m.TableSchema
}
return nil
}
func (m *SnapshotDataManifest) GetRegionManifests() []*SnapshotRegionManifest {
if m != nil {
return m.RegionManifests
}
return nil
}
func init() {
proto1.RegisterEnum("proto.SnapshotFileInfo_Type", SnapshotFileInfo_Type_name, SnapshotFileInfo_Type_value)
}

44
vendor/github.com/pingcap/go-hbase/proto/Tracing.pb.go generated vendored Normal file
View file

@ -0,0 +1,44 @@
// Code generated by protoc-gen-go.
// source: Tracing.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
// Used to pass through the information necessary to continue
// a trace after an RPC is made. All we need is the traceid
// (so we know the overarching trace this message is a part of), and
// the id of the current span when this message was sent, so we know
// what span caused the new span we will create when this message is received.
type RPCTInfo struct {
TraceId *int64 `protobuf:"varint,1,opt,name=trace_id" json:"trace_id,omitempty"`
ParentId *int64 `protobuf:"varint,2,opt,name=parent_id" json:"parent_id,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RPCTInfo) Reset() { *m = RPCTInfo{} }
func (m *RPCTInfo) String() string { return proto1.CompactTextString(m) }
func (*RPCTInfo) ProtoMessage() {}
func (m *RPCTInfo) GetTraceId() int64 {
if m != nil && m.TraceId != nil {
return *m.TraceId
}
return 0
}
func (m *RPCTInfo) GetParentId() int64 {
if m != nil && m.ParentId != nil {
return *m.ParentId
}
return 0
}
func init() {
}

View file

@ -0,0 +1,207 @@
// Code generated by protoc-gen-go.
// source: VisibilityLabels.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type VisibilityLabelsRequest struct {
VisLabel []*VisibilityLabel `protobuf:"bytes,1,rep,name=visLabel" json:"visLabel,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *VisibilityLabelsRequest) Reset() { *m = VisibilityLabelsRequest{} }
func (m *VisibilityLabelsRequest) String() string { return proto1.CompactTextString(m) }
func (*VisibilityLabelsRequest) ProtoMessage() {}
func (m *VisibilityLabelsRequest) GetVisLabel() []*VisibilityLabel {
if m != nil {
return m.VisLabel
}
return nil
}
type VisibilityLabel struct {
Label []byte `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
Ordinal *uint32 `protobuf:"varint,2,opt,name=ordinal" json:"ordinal,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *VisibilityLabel) Reset() { *m = VisibilityLabel{} }
func (m *VisibilityLabel) String() string { return proto1.CompactTextString(m) }
func (*VisibilityLabel) ProtoMessage() {}
func (m *VisibilityLabel) GetLabel() []byte {
if m != nil {
return m.Label
}
return nil
}
func (m *VisibilityLabel) GetOrdinal() uint32 {
if m != nil && m.Ordinal != nil {
return *m.Ordinal
}
return 0
}
type VisibilityLabelsResponse struct {
Result []*RegionActionResult `protobuf:"bytes,1,rep,name=result" json:"result,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *VisibilityLabelsResponse) Reset() { *m = VisibilityLabelsResponse{} }
func (m *VisibilityLabelsResponse) String() string { return proto1.CompactTextString(m) }
func (*VisibilityLabelsResponse) ProtoMessage() {}
func (m *VisibilityLabelsResponse) GetResult() []*RegionActionResult {
if m != nil {
return m.Result
}
return nil
}
type SetAuthsRequest struct {
User []byte `protobuf:"bytes,1,req,name=user" json:"user,omitempty"`
Auth [][]byte `protobuf:"bytes,2,rep,name=auth" json:"auth,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SetAuthsRequest) Reset() { *m = SetAuthsRequest{} }
func (m *SetAuthsRequest) String() string { return proto1.CompactTextString(m) }
func (*SetAuthsRequest) ProtoMessage() {}
func (m *SetAuthsRequest) GetUser() []byte {
if m != nil {
return m.User
}
return nil
}
func (m *SetAuthsRequest) GetAuth() [][]byte {
if m != nil {
return m.Auth
}
return nil
}
type UserAuthorizations struct {
User []byte `protobuf:"bytes,1,req,name=user" json:"user,omitempty"`
Auth []uint32 `protobuf:"varint,2,rep,name=auth" json:"auth,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *UserAuthorizations) Reset() { *m = UserAuthorizations{} }
func (m *UserAuthorizations) String() string { return proto1.CompactTextString(m) }
func (*UserAuthorizations) ProtoMessage() {}
func (m *UserAuthorizations) GetUser() []byte {
if m != nil {
return m.User
}
return nil
}
func (m *UserAuthorizations) GetAuth() []uint32 {
if m != nil {
return m.Auth
}
return nil
}
type MultiUserAuthorizations struct {
UserAuths []*UserAuthorizations `protobuf:"bytes,1,rep,name=userAuths" json:"userAuths,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *MultiUserAuthorizations) Reset() { *m = MultiUserAuthorizations{} }
func (m *MultiUserAuthorizations) String() string { return proto1.CompactTextString(m) }
func (*MultiUserAuthorizations) ProtoMessage() {}
func (m *MultiUserAuthorizations) GetUserAuths() []*UserAuthorizations {
if m != nil {
return m.UserAuths
}
return nil
}
type GetAuthsRequest struct {
User []byte `protobuf:"bytes,1,req,name=user" json:"user,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetAuthsRequest) Reset() { *m = GetAuthsRequest{} }
func (m *GetAuthsRequest) String() string { return proto1.CompactTextString(m) }
func (*GetAuthsRequest) ProtoMessage() {}
func (m *GetAuthsRequest) GetUser() []byte {
if m != nil {
return m.User
}
return nil
}
type GetAuthsResponse struct {
User []byte `protobuf:"bytes,1,req,name=user" json:"user,omitempty"`
Auth [][]byte `protobuf:"bytes,2,rep,name=auth" json:"auth,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *GetAuthsResponse) Reset() { *m = GetAuthsResponse{} }
func (m *GetAuthsResponse) String() string { return proto1.CompactTextString(m) }
func (*GetAuthsResponse) ProtoMessage() {}
func (m *GetAuthsResponse) GetUser() []byte {
if m != nil {
return m.User
}
return nil
}
func (m *GetAuthsResponse) GetAuth() [][]byte {
if m != nil {
return m.Auth
}
return nil
}
type ListLabelsRequest struct {
Regex *string `protobuf:"bytes,1,opt,name=regex" json:"regex,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ListLabelsRequest) Reset() { *m = ListLabelsRequest{} }
func (m *ListLabelsRequest) String() string { return proto1.CompactTextString(m) }
func (*ListLabelsRequest) ProtoMessage() {}
func (m *ListLabelsRequest) GetRegex() string {
if m != nil && m.Regex != nil {
return *m.Regex
}
return ""
}
type ListLabelsResponse struct {
Label [][]byte `protobuf:"bytes,1,rep,name=label" json:"label,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ListLabelsResponse) Reset() { *m = ListLabelsResponse{} }
func (m *ListLabelsResponse) String() string { return proto1.CompactTextString(m) }
func (*ListLabelsResponse) ProtoMessage() {}
func (m *ListLabelsResponse) GetLabel() [][]byte {
if m != nil {
return m.Label
}
return nil
}
func init() {
}

298
vendor/github.com/pingcap/go-hbase/proto/WAL.pb.go generated vendored Normal file
View file

@ -0,0 +1,298 @@
// Code generated by protoc-gen-go.
// source: WAL.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type ScopeType int32
const (
ScopeType_REPLICATION_SCOPE_LOCAL ScopeType = 0
ScopeType_REPLICATION_SCOPE_GLOBAL ScopeType = 1
)
var ScopeType_name = map[int32]string{
0: "REPLICATION_SCOPE_LOCAL",
1: "REPLICATION_SCOPE_GLOBAL",
}
var ScopeType_value = map[string]int32{
"REPLICATION_SCOPE_LOCAL": 0,
"REPLICATION_SCOPE_GLOBAL": 1,
}
func (x ScopeType) Enum() *ScopeType {
p := new(ScopeType)
*p = x
return p
}
func (x ScopeType) String() string {
return proto1.EnumName(ScopeType_name, int32(x))
}
func (x *ScopeType) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(ScopeType_value, data, "ScopeType")
if err != nil {
return err
}
*x = ScopeType(value)
return nil
}
type WALHeader struct {
HasCompression *bool `protobuf:"varint,1,opt,name=has_compression" json:"has_compression,omitempty"`
EncryptionKey []byte `protobuf:"bytes,2,opt,name=encryption_key" json:"encryption_key,omitempty"`
HasTagCompression *bool `protobuf:"varint,3,opt,name=has_tag_compression" json:"has_tag_compression,omitempty"`
WriterClsName *string `protobuf:"bytes,4,opt,name=writer_cls_name" json:"writer_cls_name,omitempty"`
CellCodecClsName *string `protobuf:"bytes,5,opt,name=cell_codec_cls_name" json:"cell_codec_cls_name,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *WALHeader) Reset() { *m = WALHeader{} }
func (m *WALHeader) String() string { return proto1.CompactTextString(m) }
func (*WALHeader) ProtoMessage() {}
func (m *WALHeader) GetHasCompression() bool {
if m != nil && m.HasCompression != nil {
return *m.HasCompression
}
return false
}
func (m *WALHeader) GetEncryptionKey() []byte {
if m != nil {
return m.EncryptionKey
}
return nil
}
func (m *WALHeader) GetHasTagCompression() bool {
if m != nil && m.HasTagCompression != nil {
return *m.HasTagCompression
}
return false
}
func (m *WALHeader) GetWriterClsName() string {
if m != nil && m.WriterClsName != nil {
return *m.WriterClsName
}
return ""
}
func (m *WALHeader) GetCellCodecClsName() string {
if m != nil && m.CellCodecClsName != nil {
return *m.CellCodecClsName
}
return ""
}
// Protocol buffer version of HLogKey; see HLogKey comment, not really a key but WALEdit header for some KVs
type WALKey struct {
EncodedRegionName []byte `protobuf:"bytes,1,req,name=encoded_region_name" json:"encoded_region_name,omitempty"`
TableName []byte `protobuf:"bytes,2,req,name=table_name" json:"table_name,omitempty"`
LogSequenceNumber *uint64 `protobuf:"varint,3,req,name=log_sequence_number" json:"log_sequence_number,omitempty"`
WriteTime *uint64 `protobuf:"varint,4,req,name=write_time" json:"write_time,omitempty"`
//
// This parameter is deprecated in favor of clusters which
// contains the list of clusters that have consumed the change.
// It is retained so that the log created by earlier releases (0.94)
// can be read by the newer releases.
ClusterId *UUID `protobuf:"bytes,5,opt,name=cluster_id" json:"cluster_id,omitempty"`
Scopes []*FamilyScope `protobuf:"bytes,6,rep,name=scopes" json:"scopes,omitempty"`
FollowingKvCount *uint32 `protobuf:"varint,7,opt,name=following_kv_count" json:"following_kv_count,omitempty"`
//
// This field contains the list of clusters that have
// consumed the change
ClusterIds []*UUID `protobuf:"bytes,8,rep,name=cluster_ids" json:"cluster_ids,omitempty"`
NonceGroup *uint64 `protobuf:"varint,9,opt,name=nonceGroup" json:"nonceGroup,omitempty"`
Nonce *uint64 `protobuf:"varint,10,opt,name=nonce" json:"nonce,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *WALKey) Reset() { *m = WALKey{} }
func (m *WALKey) String() string { return proto1.CompactTextString(m) }
func (*WALKey) ProtoMessage() {}
func (m *WALKey) GetEncodedRegionName() []byte {
if m != nil {
return m.EncodedRegionName
}
return nil
}
func (m *WALKey) GetTableName() []byte {
if m != nil {
return m.TableName
}
return nil
}
func (m *WALKey) GetLogSequenceNumber() uint64 {
if m != nil && m.LogSequenceNumber != nil {
return *m.LogSequenceNumber
}
return 0
}
func (m *WALKey) GetWriteTime() uint64 {
if m != nil && m.WriteTime != nil {
return *m.WriteTime
}
return 0
}
func (m *WALKey) GetClusterId() *UUID {
if m != nil {
return m.ClusterId
}
return nil
}
func (m *WALKey) GetScopes() []*FamilyScope {
if m != nil {
return m.Scopes
}
return nil
}
func (m *WALKey) GetFollowingKvCount() uint32 {
if m != nil && m.FollowingKvCount != nil {
return *m.FollowingKvCount
}
return 0
}
func (m *WALKey) GetClusterIds() []*UUID {
if m != nil {
return m.ClusterIds
}
return nil
}
func (m *WALKey) GetNonceGroup() uint64 {
if m != nil && m.NonceGroup != nil {
return *m.NonceGroup
}
return 0
}
func (m *WALKey) GetNonce() uint64 {
if m != nil && m.Nonce != nil {
return *m.Nonce
}
return 0
}
type FamilyScope struct {
Family []byte `protobuf:"bytes,1,req,name=family" json:"family,omitempty"`
ScopeType *ScopeType `protobuf:"varint,2,req,name=scope_type,enum=proto.ScopeType" json:"scope_type,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *FamilyScope) Reset() { *m = FamilyScope{} }
func (m *FamilyScope) String() string { return proto1.CompactTextString(m) }
func (*FamilyScope) ProtoMessage() {}
func (m *FamilyScope) GetFamily() []byte {
if m != nil {
return m.Family
}
return nil
}
func (m *FamilyScope) GetScopeType() ScopeType {
if m != nil && m.ScopeType != nil {
return *m.ScopeType
}
return ScopeType_REPLICATION_SCOPE_LOCAL
}
// *
// Special WAL entry to hold all related to a compaction.
// Written to WAL before completing compaction. There is
// sufficient info in the below message to complete later
// the * compaction should we fail the WAL write.
type CompactionDescriptor struct {
TableName []byte `protobuf:"bytes,1,req,name=table_name" json:"table_name,omitempty"`
EncodedRegionName []byte `protobuf:"bytes,2,req,name=encoded_region_name" json:"encoded_region_name,omitempty"`
FamilyName []byte `protobuf:"bytes,3,req,name=family_name" json:"family_name,omitempty"`
CompactionInput []string `protobuf:"bytes,4,rep,name=compaction_input" json:"compaction_input,omitempty"`
CompactionOutput []string `protobuf:"bytes,5,rep,name=compaction_output" json:"compaction_output,omitempty"`
StoreHomeDir *string `protobuf:"bytes,6,req,name=store_home_dir" json:"store_home_dir,omitempty"`
RegionName []byte `protobuf:"bytes,7,opt,name=region_name" json:"region_name,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *CompactionDescriptor) Reset() { *m = CompactionDescriptor{} }
func (m *CompactionDescriptor) String() string { return proto1.CompactTextString(m) }
func (*CompactionDescriptor) ProtoMessage() {}
func (m *CompactionDescriptor) GetTableName() []byte {
if m != nil {
return m.TableName
}
return nil
}
func (m *CompactionDescriptor) GetEncodedRegionName() []byte {
if m != nil {
return m.EncodedRegionName
}
return nil
}
func (m *CompactionDescriptor) GetFamilyName() []byte {
if m != nil {
return m.FamilyName
}
return nil
}
func (m *CompactionDescriptor) GetCompactionInput() []string {
if m != nil {
return m.CompactionInput
}
return nil
}
func (m *CompactionDescriptor) GetCompactionOutput() []string {
if m != nil {
return m.CompactionOutput
}
return nil
}
func (m *CompactionDescriptor) GetStoreHomeDir() string {
if m != nil && m.StoreHomeDir != nil {
return *m.StoreHomeDir
}
return ""
}
func (m *CompactionDescriptor) GetRegionName() []byte {
if m != nil {
return m.RegionName
}
return nil
}
// *
// A trailer that is appended to the end of a properly closed HLog WAL file.
// If missing, this is either a legacy or a corrupted WAL file.
type WALTrailer struct {
XXX_unrecognized []byte `json:"-"`
}
func (m *WALTrailer) Reset() { *m = WALTrailer{} }
func (m *WALTrailer) String() string { return proto1.CompactTextString(m) }
func (*WALTrailer) ProtoMessage() {}
func init() {
proto1.RegisterEnum("proto.ScopeType", ScopeType_name, ScopeType_value)
}

View file

@ -0,0 +1,580 @@
// Code generated by protoc-gen-go.
// source: ZooKeeper.proto
// DO NOT EDIT!
package proto
import proto1 "github.com/golang/protobuf/proto"
import math "math"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto1.Marshal
var _ = math.Inf
type SplitLogTask_State int32
const (
SplitLogTask_UNASSIGNED SplitLogTask_State = 0
SplitLogTask_OWNED SplitLogTask_State = 1
SplitLogTask_RESIGNED SplitLogTask_State = 2
SplitLogTask_DONE SplitLogTask_State = 3
SplitLogTask_ERR SplitLogTask_State = 4
)
var SplitLogTask_State_name = map[int32]string{
0: "UNASSIGNED",
1: "OWNED",
2: "RESIGNED",
3: "DONE",
4: "ERR",
}
var SplitLogTask_State_value = map[string]int32{
"UNASSIGNED": 0,
"OWNED": 1,
"RESIGNED": 2,
"DONE": 3,
"ERR": 4,
}
func (x SplitLogTask_State) Enum() *SplitLogTask_State {
p := new(SplitLogTask_State)
*p = x
return p
}
func (x SplitLogTask_State) String() string {
return proto1.EnumName(SplitLogTask_State_name, int32(x))
}
func (x *SplitLogTask_State) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(SplitLogTask_State_value, data, "SplitLogTask_State")
if err != nil {
return err
}
*x = SplitLogTask_State(value)
return nil
}
type SplitLogTask_RecoveryMode int32
const (
SplitLogTask_UNKNOWN SplitLogTask_RecoveryMode = 0
SplitLogTask_LOG_SPLITTING SplitLogTask_RecoveryMode = 1
SplitLogTask_LOG_REPLAY SplitLogTask_RecoveryMode = 2
)
var SplitLogTask_RecoveryMode_name = map[int32]string{
0: "UNKNOWN",
1: "LOG_SPLITTING",
2: "LOG_REPLAY",
}
var SplitLogTask_RecoveryMode_value = map[string]int32{
"UNKNOWN": 0,
"LOG_SPLITTING": 1,
"LOG_REPLAY": 2,
}
func (x SplitLogTask_RecoveryMode) Enum() *SplitLogTask_RecoveryMode {
p := new(SplitLogTask_RecoveryMode)
*p = x
return p
}
func (x SplitLogTask_RecoveryMode) String() string {
return proto1.EnumName(SplitLogTask_RecoveryMode_name, int32(x))
}
func (x *SplitLogTask_RecoveryMode) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(SplitLogTask_RecoveryMode_value, data, "SplitLogTask_RecoveryMode")
if err != nil {
return err
}
*x = SplitLogTask_RecoveryMode(value)
return nil
}
// Table's current state
type Table_State int32
const (
Table_ENABLED Table_State = 0
Table_DISABLED Table_State = 1
Table_DISABLING Table_State = 2
Table_ENABLING Table_State = 3
)
var Table_State_name = map[int32]string{
0: "ENABLED",
1: "DISABLED",
2: "DISABLING",
3: "ENABLING",
}
var Table_State_value = map[string]int32{
"ENABLED": 0,
"DISABLED": 1,
"DISABLING": 2,
"ENABLING": 3,
}
func (x Table_State) Enum() *Table_State {
p := new(Table_State)
*p = x
return p
}
func (x Table_State) String() string {
return proto1.EnumName(Table_State_name, int32(x))
}
func (x *Table_State) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(Table_State_value, data, "Table_State")
if err != nil {
return err
}
*x = Table_State(value)
return nil
}
type ReplicationState_State int32
const (
ReplicationState_ENABLED ReplicationState_State = 0
ReplicationState_DISABLED ReplicationState_State = 1
)
var ReplicationState_State_name = map[int32]string{
0: "ENABLED",
1: "DISABLED",
}
var ReplicationState_State_value = map[string]int32{
"ENABLED": 0,
"DISABLED": 1,
}
func (x ReplicationState_State) Enum() *ReplicationState_State {
p := new(ReplicationState_State)
*p = x
return p
}
func (x ReplicationState_State) String() string {
return proto1.EnumName(ReplicationState_State_name, int32(x))
}
func (x *ReplicationState_State) UnmarshalJSON(data []byte) error {
value, err := proto1.UnmarshalJSONEnum(ReplicationState_State_value, data, "ReplicationState_State")
if err != nil {
return err
}
*x = ReplicationState_State(value)
return nil
}
// *
// Content of the meta-region-server znode.
type MetaRegionServer struct {
// The ServerName hosting the meta region currently.
Server *ServerName `protobuf:"bytes,1,req,name=server" json:"server,omitempty"`
// The major version of the rpc the server speaks. This is used so that
// clients connecting to the cluster can have prior knowledge of what version
// to send to a RegionServer. AsyncHBase will use this to detect versions.
RpcVersion *uint32 `protobuf:"varint,2,opt,name=rpc_version" json:"rpc_version,omitempty"`
// State of the region transition. OPEN means fully operational 'hbase:meta'
State *RegionState_State `protobuf:"varint,3,opt,name=state,enum=proto.RegionState_State" json:"state,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *MetaRegionServer) Reset() { *m = MetaRegionServer{} }
func (m *MetaRegionServer) String() string { return proto1.CompactTextString(m) }
func (*MetaRegionServer) ProtoMessage() {}
func (m *MetaRegionServer) GetServer() *ServerName {
if m != nil {
return m.Server
}
return nil
}
func (m *MetaRegionServer) GetRpcVersion() uint32 {
if m != nil && m.RpcVersion != nil {
return *m.RpcVersion
}
return 0
}
func (m *MetaRegionServer) GetState() RegionState_State {
if m != nil && m.State != nil {
return *m.State
}
return RegionState_OFFLINE
}
// *
// Content of the master znode.
type Master struct {
// The ServerName of the current Master
Master *ServerName `protobuf:"bytes,1,req,name=master" json:"master,omitempty"`
// Major RPC version so that clients can know what version the master can accept.
RpcVersion *uint32 `protobuf:"varint,2,opt,name=rpc_version" json:"rpc_version,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Master) Reset() { *m = Master{} }
func (m *Master) String() string { return proto1.CompactTextString(m) }
func (*Master) ProtoMessage() {}
func (m *Master) GetMaster() *ServerName {
if m != nil {
return m.Master
}
return nil
}
func (m *Master) GetRpcVersion() uint32 {
if m != nil && m.RpcVersion != nil {
return *m.RpcVersion
}
return 0
}
// *
// Content of the '/hbase/running', cluster state, znode.
type ClusterUp struct {
// If this znode is present, cluster is up. Currently
// the data is cluster start_date.
StartDate *string `protobuf:"bytes,1,req,name=start_date" json:"start_date,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ClusterUp) Reset() { *m = ClusterUp{} }
func (m *ClusterUp) String() string { return proto1.CompactTextString(m) }
func (*ClusterUp) ProtoMessage() {}
func (m *ClusterUp) GetStartDate() string {
if m != nil && m.StartDate != nil {
return *m.StartDate
}
return ""
}
// *
// What we write under unassigned up in zookeeper as a region moves through
// open/close, etc., regions. Details a region in transition.
type RegionTransition struct {
// Code for EventType gotten by doing o.a.h.h.EventHandler.EventType.getCode()
EventTypeCode *uint32 `protobuf:"varint,1,req,name=event_type_code" json:"event_type_code,omitempty"`
// Full regionname in bytes
RegionName []byte `protobuf:"bytes,2,req,name=region_name" json:"region_name,omitempty"`
CreateTime *uint64 `protobuf:"varint,3,req,name=create_time" json:"create_time,omitempty"`
// The region server where the transition will happen or is happening
ServerName *ServerName `protobuf:"bytes,4,req,name=server_name" json:"server_name,omitempty"`
Payload []byte `protobuf:"bytes,5,opt,name=payload" json:"payload,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionTransition) Reset() { *m = RegionTransition{} }
func (m *RegionTransition) String() string { return proto1.CompactTextString(m) }
func (*RegionTransition) ProtoMessage() {}
func (m *RegionTransition) GetEventTypeCode() uint32 {
if m != nil && m.EventTypeCode != nil {
return *m.EventTypeCode
}
return 0
}
func (m *RegionTransition) GetRegionName() []byte {
if m != nil {
return m.RegionName
}
return nil
}
func (m *RegionTransition) GetCreateTime() uint64 {
if m != nil && m.CreateTime != nil {
return *m.CreateTime
}
return 0
}
func (m *RegionTransition) GetServerName() *ServerName {
if m != nil {
return m.ServerName
}
return nil
}
func (m *RegionTransition) GetPayload() []byte {
if m != nil {
return m.Payload
}
return nil
}
// *
// WAL SplitLog directory znodes have this for content. Used doing distributed
// WAL splitting. Holds current state and name of server that originated split.
type SplitLogTask struct {
State *SplitLogTask_State `protobuf:"varint,1,req,name=state,enum=proto.SplitLogTask_State" json:"state,omitempty"`
ServerName *ServerName `protobuf:"bytes,2,req,name=server_name" json:"server_name,omitempty"`
Mode *SplitLogTask_RecoveryMode `protobuf:"varint,3,opt,name=mode,enum=proto.SplitLogTask_RecoveryMode,def=0" json:"mode,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *SplitLogTask) Reset() { *m = SplitLogTask{} }
func (m *SplitLogTask) String() string { return proto1.CompactTextString(m) }
func (*SplitLogTask) ProtoMessage() {}
const Default_SplitLogTask_Mode SplitLogTask_RecoveryMode = SplitLogTask_UNKNOWN
func (m *SplitLogTask) GetState() SplitLogTask_State {
if m != nil && m.State != nil {
return *m.State
}
return SplitLogTask_UNASSIGNED
}
func (m *SplitLogTask) GetServerName() *ServerName {
if m != nil {
return m.ServerName
}
return nil
}
func (m *SplitLogTask) GetMode() SplitLogTask_RecoveryMode {
if m != nil && m.Mode != nil {
return *m.Mode
}
return Default_SplitLogTask_Mode
}
// *
// The znode that holds state of table.
type Table struct {
// This is the table's state. If no znode for a table,
// its state is presumed enabled. See o.a.h.h.zookeeper.ZKTable class
// for more.
State *Table_State `protobuf:"varint,1,req,name=state,enum=proto.Table_State,def=0" json:"state,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Table) Reset() { *m = Table{} }
func (m *Table) String() string { return proto1.CompactTextString(m) }
func (*Table) ProtoMessage() {}
const Default_Table_State Table_State = Table_ENABLED
func (m *Table) GetState() Table_State {
if m != nil && m.State != nil {
return *m.State
}
return Default_Table_State
}
// *
// Used by replication. Holds a replication peer key.
type ReplicationPeer struct {
// clusterkey is the concatenation of the slave cluster's
// hbase.zookeeper.quorum:hbase.zookeeper.property.clientPort:zookeeper.znode.parent
Clusterkey *string `protobuf:"bytes,1,req,name=clusterkey" json:"clusterkey,omitempty"`
ReplicationEndpointImpl *string `protobuf:"bytes,2,opt,name=replicationEndpointImpl" json:"replicationEndpointImpl,omitempty"`
Data []*BytesBytesPair `protobuf:"bytes,3,rep,name=data" json:"data,omitempty"`
Configuration []*NameStringPair `protobuf:"bytes,4,rep,name=configuration" json:"configuration,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ReplicationPeer) Reset() { *m = ReplicationPeer{} }
func (m *ReplicationPeer) String() string { return proto1.CompactTextString(m) }
func (*ReplicationPeer) ProtoMessage() {}
func (m *ReplicationPeer) GetClusterkey() string {
if m != nil && m.Clusterkey != nil {
return *m.Clusterkey
}
return ""
}
func (m *ReplicationPeer) GetReplicationEndpointImpl() string {
if m != nil && m.ReplicationEndpointImpl != nil {
return *m.ReplicationEndpointImpl
}
return ""
}
func (m *ReplicationPeer) GetData() []*BytesBytesPair {
if m != nil {
return m.Data
}
return nil
}
func (m *ReplicationPeer) GetConfiguration() []*NameStringPair {
if m != nil {
return m.Configuration
}
return nil
}
// *
// Used by replication. Holds whether enabled or disabled
type ReplicationState struct {
State *ReplicationState_State `protobuf:"varint,1,req,name=state,enum=proto.ReplicationState_State" json:"state,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ReplicationState) Reset() { *m = ReplicationState{} }
func (m *ReplicationState) String() string { return proto1.CompactTextString(m) }
func (*ReplicationState) ProtoMessage() {}
func (m *ReplicationState) GetState() ReplicationState_State {
if m != nil && m.State != nil {
return *m.State
}
return ReplicationState_ENABLED
}
// *
// Used by replication. Holds the current position in an HLog file.
type ReplicationHLogPosition struct {
Position *int64 `protobuf:"varint,1,req,name=position" json:"position,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ReplicationHLogPosition) Reset() { *m = ReplicationHLogPosition{} }
func (m *ReplicationHLogPosition) String() string { return proto1.CompactTextString(m) }
func (*ReplicationHLogPosition) ProtoMessage() {}
func (m *ReplicationHLogPosition) GetPosition() int64 {
if m != nil && m.Position != nil {
return *m.Position
}
return 0
}
// *
// Used by replication. Used to lock a region server during failover.
type ReplicationLock struct {
LockOwner *string `protobuf:"bytes,1,req,name=lock_owner" json:"lock_owner,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ReplicationLock) Reset() { *m = ReplicationLock{} }
func (m *ReplicationLock) String() string { return proto1.CompactTextString(m) }
func (*ReplicationLock) ProtoMessage() {}
func (m *ReplicationLock) GetLockOwner() string {
if m != nil && m.LockOwner != nil {
return *m.LockOwner
}
return ""
}
// *
// Metadata associated with a table lock in zookeeper
type TableLock struct {
TableName *TableName `protobuf:"bytes,1,opt,name=table_name" json:"table_name,omitempty"`
LockOwner *ServerName `protobuf:"bytes,2,opt,name=lock_owner" json:"lock_owner,omitempty"`
ThreadId *int64 `protobuf:"varint,3,opt,name=thread_id" json:"thread_id,omitempty"`
IsShared *bool `protobuf:"varint,4,opt,name=is_shared" json:"is_shared,omitempty"`
Purpose *string `protobuf:"bytes,5,opt,name=purpose" json:"purpose,omitempty"`
CreateTime *int64 `protobuf:"varint,6,opt,name=create_time" json:"create_time,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *TableLock) Reset() { *m = TableLock{} }
func (m *TableLock) String() string { return proto1.CompactTextString(m) }
func (*TableLock) ProtoMessage() {}
func (m *TableLock) GetTableName() *TableName {
if m != nil {
return m.TableName
}
return nil
}
func (m *TableLock) GetLockOwner() *ServerName {
if m != nil {
return m.LockOwner
}
return nil
}
func (m *TableLock) GetThreadId() int64 {
if m != nil && m.ThreadId != nil {
return *m.ThreadId
}
return 0
}
func (m *TableLock) GetIsShared() bool {
if m != nil && m.IsShared != nil {
return *m.IsShared
}
return false
}
func (m *TableLock) GetPurpose() string {
if m != nil && m.Purpose != nil {
return *m.Purpose
}
return ""
}
func (m *TableLock) GetCreateTime() int64 {
if m != nil && m.CreateTime != nil {
return *m.CreateTime
}
return 0
}
// *
// sequence Id of a store
type StoreSequenceId struct {
FamilyName []byte `protobuf:"bytes,1,req,name=family_name" json:"family_name,omitempty"`
SequenceId *uint64 `protobuf:"varint,2,req,name=sequence_id" json:"sequence_id,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *StoreSequenceId) Reset() { *m = StoreSequenceId{} }
func (m *StoreSequenceId) String() string { return proto1.CompactTextString(m) }
func (*StoreSequenceId) ProtoMessage() {}
func (m *StoreSequenceId) GetFamilyName() []byte {
if m != nil {
return m.FamilyName
}
return nil
}
func (m *StoreSequenceId) GetSequenceId() uint64 {
if m != nil && m.SequenceId != nil {
return *m.SequenceId
}
return 0
}
// *
// contains a sequence id of a region which should be the minimum of its store sequence ids and
// list sequence ids of the region's stores
type RegionStoreSequenceIds struct {
LastFlushedSequenceId *uint64 `protobuf:"varint,1,req,name=last_flushed_sequence_id" json:"last_flushed_sequence_id,omitempty"`
StoreSequenceId []*StoreSequenceId `protobuf:"bytes,2,rep,name=store_sequence_id" json:"store_sequence_id,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *RegionStoreSequenceIds) Reset() { *m = RegionStoreSequenceIds{} }
func (m *RegionStoreSequenceIds) String() string { return proto1.CompactTextString(m) }
func (*RegionStoreSequenceIds) ProtoMessage() {}
func (m *RegionStoreSequenceIds) GetLastFlushedSequenceId() uint64 {
if m != nil && m.LastFlushedSequenceId != nil {
return *m.LastFlushedSequenceId
}
return 0
}
func (m *RegionStoreSequenceIds) GetStoreSequenceId() []*StoreSequenceId {
if m != nil {
return m.StoreSequenceId
}
return nil
}
func init() {
proto1.RegisterEnum("proto.SplitLogTask_State", SplitLogTask_State_name, SplitLogTask_State_value)
proto1.RegisterEnum("proto.SplitLogTask_RecoveryMode", SplitLogTask_RecoveryMode_name, SplitLogTask_RecoveryMode_value)
proto1.RegisterEnum("proto.Table_State", Table_State_name, Table_State_value)
proto1.RegisterEnum("proto.ReplicationState_State", ReplicationState_State_name, ReplicationState_State_value)
}

92
vendor/github.com/pingcap/go-hbase/put.go generated vendored Normal file
View file

@ -0,0 +1,92 @@
package hbase
import (
"bytes"
"math"
pb "github.com/golang/protobuf/proto"
"github.com/pingcap/go-hbase/proto"
)
type Put struct {
Row []byte
Families [][]byte
Qualifiers [][][]byte
Values [][][]byte
Timestamp uint64
}
func NewPut(row []byte) *Put {
return &Put{
Row: row,
Families: make([][]byte, 0),
Qualifiers: make([][][]byte, 0),
Values: make([][][]byte, 0),
}
}
func (p *Put) GetRow() []byte {
return p.Row
}
func (p *Put) AddValue(family, qual, value []byte) *Put {
pos := p.posOfFamily(family)
if pos == -1 {
p.Families = append(p.Families, family)
p.Qualifiers = append(p.Qualifiers, make([][]byte, 0))
p.Values = append(p.Values, make([][]byte, 0))
pos = p.posOfFamily(family)
}
p.Qualifiers[pos] = append(p.Qualifiers[pos], qual)
p.Values[pos] = append(p.Values[pos], value)
return p
}
func (p *Put) AddStringValue(family, column, value string) *Put {
return p.AddValue([]byte(family), []byte(column), []byte(value))
}
func (p *Put) AddTimestamp(ts uint64) *Put {
if ts == 0 {
p.Timestamp = math.MaxInt64
} else {
p.Timestamp = ts
}
return p
}
func (p *Put) posOfFamily(family []byte) int {
for p, v := range p.Families {
if bytes.Equal(family, v) {
return p
}
}
return -1
}
func (p *Put) ToProto() pb.Message {
put := &proto.MutationProto{
Row: p.Row,
MutateType: proto.MutationProto_PUT.Enum(),
}
for i, family := range p.Families {
cv := &proto.MutationProto_ColumnValue{
Family: family,
}
for j := range p.Qualifiers[i] {
cv.QualifierValue = append(cv.QualifierValue, &proto.MutationProto_ColumnValue_QualifierValue{
Qualifier: p.Qualifiers[i][j],
Value: p.Values[i][j],
Timestamp: pb.Uint64(p.Timestamp),
})
}
put.ColumnValue = append(put.ColumnValue, cv)
}
return put
}

76
vendor/github.com/pingcap/go-hbase/result.go generated vendored Normal file
View file

@ -0,0 +1,76 @@
package hbase
import (
"fmt"
"github.com/pingcap/go-hbase/proto"
)
type Kv struct {
Row []byte
Ts uint64
Value []byte
// history results
Values map[uint64][]byte
Column
}
func (kv *Kv) String() string {
if kv == nil {
return "<nil>"
}
return fmt.Sprintf("Kv(%+v)", *kv)
}
type ResultRow struct {
Row []byte
Columns map[string]*Kv
SortedColumns []*Kv
}
func (r *ResultRow) String() string {
if r == nil {
return "<nil>"
}
return fmt.Sprintf("ResultRow(%+v)", *r)
}
func NewResultRow(result *proto.Result) *ResultRow {
// empty response
if len(result.GetCell()) == 0 {
return nil
}
res := &ResultRow{}
res.Columns = make(map[string]*Kv)
res.SortedColumns = make([]*Kv, 0)
for _, cell := range result.GetCell() {
res.Row = cell.GetRow()
col := &Kv{
Row: res.Row,
Column: Column{
Family: cell.GetFamily(),
Qual: cell.GetQualifier(),
},
Value: cell.GetValue(),
Ts: cell.GetTimestamp(),
}
colName := string(col.Column.Family) + ":" + string(col.Column.Qual)
if v, exists := res.Columns[colName]; exists {
// renew the same cf result
if col.Ts > v.Ts {
v.Value = col.Value
v.Ts = col.Ts
}
v.Values[col.Ts] = col.Value
} else {
col.Values = map[uint64][]byte{col.Ts: col.Value}
res.Columns[colName] = col
res.SortedColumns = append(res.SortedColumns, col)
}
}
return res
}

397
vendor/github.com/pingcap/go-hbase/scan.go generated vendored Normal file
View file

@ -0,0 +1,397 @@
package hbase
import (
"bytes"
pb "github.com/golang/protobuf/proto"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase/proto"
)
// nextKey returns the next key in byte-order.
// for example:
// nil -> [0]
// [] -> [0]
// [0] -> [1]
// [1, 2, 3] -> [1, 2, 4]
// [1, 255] -> [2, 0]
// [255] -> [0, 0]
func nextKey(data []byte) []byte {
// nil or []byte{}
dataLen := len(data)
if dataLen == 0 {
return []byte{0}
}
// Check and process carry bit.
i := dataLen - 1
data[i]++
for i > 0 {
if data[i] == 0 {
i--
data[i]++
} else {
break
}
}
// Check whether need to add another byte for carry bit,
// like [255] -> [0, 0]
if data[i] == 0 {
data = append([]byte{0}, data...)
}
return data
}
const (
defaultScanMaxRetries = 3
)
type Scan struct {
client *client
id uint64
table []byte
// row key
StartRow []byte
StopRow []byte
families [][]byte
qualifiers [][][]byte
nextStartKey []byte
numCached int
closed bool
location *RegionInfo
server *connection
cache []*ResultRow
attrs map[string][]byte
MaxVersions uint32
TsRangeFrom uint64
TsRangeTo uint64
lastResult *ResultRow
// if region split, set startKey = lastResult.Row, but must skip the first
skipFirst bool
maxRetries int
}
func NewScan(table []byte, batchSize int, c HBaseClient) *Scan {
if batchSize <= 0 {
batchSize = 100
}
return &Scan{
client: c.(*client),
table: table,
nextStartKey: nil,
families: make([][]byte, 0),
qualifiers: make([][][]byte, 0),
numCached: batchSize,
closed: false,
attrs: make(map[string][]byte),
maxRetries: defaultScanMaxRetries,
}
}
func (s *Scan) Close() error {
if s.closed {
return nil
}
err := s.closeScan(s.server, s.location, s.id)
if err != nil {
return errors.Trace(err)
}
s.closed = true
return nil
}
func (s *Scan) AddColumn(family, qual []byte) {
s.AddFamily(family)
pos := s.posOfFamily(family)
s.qualifiers[pos] = append(s.qualifiers[pos], qual)
}
func (s *Scan) AddStringColumn(family, qual string) {
s.AddColumn([]byte(family), []byte(qual))
}
func (s *Scan) AddFamily(family []byte) {
pos := s.posOfFamily(family)
if pos == -1 {
s.families = append(s.families, family)
s.qualifiers = append(s.qualifiers, make([][]byte, 0))
}
}
func (s *Scan) AddStringFamily(family string) {
s.AddFamily([]byte(family))
}
func (s *Scan) posOfFamily(family []byte) int {
for p, v := range s.families {
if bytes.Equal(family, v) {
return p
}
}
return -1
}
func (s *Scan) AddAttr(name string, val []byte) {
s.attrs[name] = val
}
func (s *Scan) AddTimeRange(from uint64, to uint64) {
s.TsRangeFrom = from
s.TsRangeTo = to
}
func (s *Scan) Closed() bool {
return s.closed
}
func (s *Scan) CreateGetFromScan(row []byte) *Get {
g := NewGet(row)
for i, family := range s.families {
if len(s.qualifiers[i]) > 0 {
for _, qual := range s.qualifiers[i] {
g.AddColumn(family, qual)
}
} else {
g.AddFamily(family)
}
}
return g
}
func (s *Scan) getData(startKey []byte, retries int) ([]*ResultRow, error) {
server, location, err := s.getServerAndLocation(s.table, startKey)
if err != nil {
return nil, errors.Trace(err)
}
req := &proto.ScanRequest{
Region: &proto.RegionSpecifier{
Type: proto.RegionSpecifier_REGION_NAME.Enum(),
Value: []byte(location.Name),
},
NumberOfRows: pb.Uint32(uint32(s.numCached)),
Scan: &proto.Scan{},
}
// set attributes
var attrs []*proto.NameBytesPair
for k, v := range s.attrs {
p := &proto.NameBytesPair{
Name: pb.String(k),
Value: v,
}
attrs = append(attrs, p)
}
if len(attrs) > 0 {
req.Scan.Attribute = attrs
}
if s.id > 0 {
req.ScannerId = pb.Uint64(s.id)
}
req.Scan.StartRow = startKey
if s.StopRow != nil {
req.Scan.StopRow = s.StopRow
}
if s.MaxVersions > 0 {
req.Scan.MaxVersions = &s.MaxVersions
}
if s.TsRangeTo > s.TsRangeFrom {
req.Scan.TimeRange = &proto.TimeRange{
From: pb.Uint64(s.TsRangeFrom),
To: pb.Uint64(s.TsRangeTo),
}
}
for i, v := range s.families {
req.Scan.Column = append(req.Scan.Column, &proto.Column{
Family: v,
Qualifier: s.qualifiers[i],
})
}
cl := newCall(req)
err = server.call(cl)
if err != nil {
return nil, errors.Trace(err)
}
msg := <-cl.responseCh
rs, err := s.processResponse(msg)
if err != nil && (isNotInRegionError(err) || isUnknownScannerError(err)) {
if retries <= s.maxRetries {
// clean this table region cache and try again
s.client.CleanRegionCache(s.table)
// create new scanner and set startRow to lastResult
s.id = 0
if s.lastResult != nil {
startKey = s.lastResult.Row
s.skipFirst = true
}
s.server = nil
s.location = nil
log.Warnf("Retryint get data for %d time(s)", retries+1)
retrySleep(retries + 1)
return s.getData(startKey, retries+1)
}
}
return rs, nil
}
func (s *Scan) processResponse(response pb.Message) ([]*ResultRow, error) {
var res *proto.ScanResponse
switch r := response.(type) {
case *proto.ScanResponse:
res = r
case *exception:
return nil, errors.New(r.msg)
default:
return nil, errors.Errorf("Invalid response seen [response: %#v]", response)
}
// Check whether response is nil.
if res == nil {
return nil, errors.Errorf("Empty response: [table=%s] [StartRow=%q] [StopRow=%q] ", s.table, s.StartRow, s.StopRow)
}
nextRegion := true
s.nextStartKey = nil
s.id = res.GetScannerId()
results := res.GetResults()
n := len(results)
if (n == s.numCached) ||
len(s.location.EndKey) == 0 ||
(s.StopRow != nil && bytes.Compare(s.location.EndKey, s.StopRow) > 0 && n < s.numCached) ||
res.GetMoreResultsInRegion() {
nextRegion = false
}
var err error
if nextRegion {
s.nextStartKey = s.location.EndKey
err = s.closeScan(s.server, s.location, s.id)
if err != nil {
return nil, errors.Trace(err)
}
s.server = nil
s.location = nil
s.id = 0
}
if n == 0 && !nextRegion {
err = s.Close()
if err != nil {
return nil, errors.Trace(err)
}
}
if s.skipFirst {
results = results[1:]
s.skipFirst = false
n = len(results)
}
tbr := make([]*ResultRow, n)
for i, v := range results {
if v != nil {
tbr[i] = NewResultRow(v)
}
}
return tbr, nil
}
func (s *Scan) nextBatch() int {
startKey := s.nextStartKey
if startKey == nil {
startKey = s.StartRow
}
// Notice: ignore error here.
// TODO: add error check, now only add a log.
rs, err := s.getData(startKey, 0)
if err != nil {
log.Errorf("scan next batch failed - [startKey=%q], %v", startKey, errors.ErrorStack(err))
}
// Current region get 0 data, try switch to next region.
if len(rs) == 0 && len(s.nextStartKey) > 0 {
// TODO: add error check, now only add a log.
rs, err = s.getData(s.nextStartKey, 0)
if err != nil {
log.Errorf("scan next batch failed - [startKey=%q], %v", s.nextStartKey, errors.ErrorStack(err))
}
}
s.cache = rs
return len(s.cache)
}
func (s *Scan) Next() *ResultRow {
if s.closed {
return nil
}
var ret *ResultRow
if len(s.cache) == 0 {
n := s.nextBatch()
// no data returned
if n == 0 {
return nil
}
}
ret = s.cache[0]
s.lastResult = ret
s.cache = s.cache[1:]
return ret
}
func (s *Scan) closeScan(server *connection, location *RegionInfo, id uint64) error {
if server == nil || location == nil {
return nil
}
req := &proto.ScanRequest{
Region: &proto.RegionSpecifier{
Type: proto.RegionSpecifier_REGION_NAME.Enum(),
Value: []byte(location.Name),
},
ScannerId: pb.Uint64(id),
CloseScanner: pb.Bool(true),
}
cl := newCall(req)
err := server.call(cl)
if err != nil {
return errors.Trace(err)
}
// TODO: add exception check.
<-cl.responseCh
return nil
}
func (s *Scan) getServerAndLocation(table, startRow []byte) (*connection, *RegionInfo, error) {
if s.server != nil && s.location != nil {
return s.server, s.location, nil
}
var err error
s.location, err = s.client.LocateRegion(table, startRow, true)
if err != nil {
return nil, nil, errors.Trace(err)
}
s.server, err = s.client.getClientConn(s.location.Server)
if err != nil {
return nil, nil, errors.Trace(err)
}
return s.server, s.location, nil
}

22
vendor/github.com/pingcap/go-hbase/service_call.go generated vendored Normal file
View file

@ -0,0 +1,22 @@
package hbase
import (
"github.com/pingcap/go-hbase/proto"
pb "github.com/golang/protobuf/proto"
)
type CoprocessorServiceCall struct {
Row []byte
ServiceName string
MethodName string
RequestParam []byte
}
func (c *CoprocessorServiceCall) ToProto() pb.Message {
return &proto.CoprocessorServiceCall{
Row: c.Row,
ServiceName: pb.String(c.ServiceName),
MethodName: pb.String(c.MethodName),
Request: c.RequestParam,
}
}

40
vendor/github.com/pingcap/go-hbase/types.go generated vendored Normal file
View file

@ -0,0 +1,40 @@
package hbase
import "bytes"
type Type byte
const (
TypeMinimum = Type(0)
TypePut = Type(4)
TypeDelete = Type(8)
TypeDeleteFamilyVersion = Type(10)
TypeDeleteColumn = Type(12)
TypeDeleteFamily = Type(14)
TypeMaximum = Type(0xff)
)
type set map[string]struct{}
func newSet() set {
return set(map[string]struct{}{})
}
func (s set) exists(k string) bool {
_, ok := s[k]
return ok
}
func (s set) add(k string) {
s[k] = struct{}{}
}
func (s set) remove(k string) {
delete(s, k)
}
type BytesSlice [][]byte
func (s BytesSlice) Len() int { return len(s) }
func (s BytesSlice) Less(i, j int) bool { return bytes.Compare(s[i], s[j]) < 0 }
func (s BytesSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

51
vendor/github.com/pingcap/go-hbase/utils.go generated vendored Normal file
View file

@ -0,0 +1,51 @@
package hbase
import (
"bytes"
"time"
"github.com/juju/errors"
"github.com/pingcap/go-hbase/proto"
)
func retrySleep(retries int) {
time.Sleep(time.Duration(retries*500) * time.Millisecond)
}
func findKey(region *RegionInfo, key []byte) bool {
if region == nil {
return false
}
// StartKey <= key < EndKey
return (len(region.StartKey) == 0 || bytes.Compare(region.StartKey, key) <= 0) &&
(len(region.EndKey) == 0 || bytes.Compare(key, region.EndKey) < 0)
}
func NewRegionSpecifier(regionName string) *proto.RegionSpecifier {
return &proto.RegionSpecifier{
Type: proto.RegionSpecifier_REGION_NAME.Enum(),
Value: []byte(regionName),
}
}
// TODO: The following functions can be moved later.
// ErrorEqual returns a boolean indicating whether err1 is equal to err2.
func ErrorEqual(err1, err2 error) bool {
e1 := errors.Cause(err1)
e2 := errors.Cause(err2)
if e1 == e2 {
return true
}
if e1 == nil || e2 == nil {
return e1 == e2
}
return e1.Error() == e2.Error()
}
// ErrorNotEqual returns a boolean indicating whether err1 isn't equal to err2.
func ErrorNotEqual(err1, err2 error) bool {
return !ErrorEqual(err1, err2)
}

22
vendor/github.com/pingcap/go-themis/LICENSE generated vendored Normal file
View file

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 PingCAP
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

30
vendor/github.com/pingcap/go-themis/README.md generated vendored Normal file
View file

@ -0,0 +1,30 @@
# go-themis
[![Build Status](https://travis-ci.org/pingcap/go-themis.svg?branch=master)](https://travis-ci.org/pingcap/go-themis)
go-themis is a Go client for [pingcap/themis](https://github.com/pingcap/themis).
Themis provides cross-row/cross-table transaction on HBase based on [google's Percolator](http://research.google.com/pubs/pub36726.html).
go-themis is depends on [pingcap/go-hbase](https://github.com/pingcap/go-hbase).
Install:
```
go get -u github.com/pingcap/go-themis
```
Example:
```
tx := themis.NewTxn(c, oracles.NewLocalOracle())
put := hbase.NewPut([]byte("Row1"))
put.AddValue([]byte("cf"), []byte("q"), []byte("value"))
put2 := hbase.NewPut([]byte("Row2"))
put2.AddValue([]byte("cf"), []byte("q"), []byte("value"))
tx.Put(tblName, put)
tx.Put(tblName, put2)
tx.Commit()
```

547
vendor/github.com/pingcap/go-themis/Themis.pb.go generated vendored Normal file
View file

@ -0,0 +1,547 @@
// Code generated by protoc-gen-go.
// source: Themis.proto
// DO NOT EDIT!
/*
Package Themis is a generated protocol buffer package.
It is generated from these files:
Themis.proto
It has these top-level messages:
ThemisGetRequest
ThemisBatchGetRequest
ThemisBatchGetResponse
ThemisPrewrite
ThemisPrewriteRequest
ThemisPrewriteResponse
ThemisBatchPrewriteSecondaryRequest
ThemisBatchPrewriteSecondaryResponse
ThemisPrewriteResult
ThemisCommitRequest
ThemisCommitResponse
ThemisBatchCommitSecondaryRequest
ThemisBatchCommitSecondaryResponse
ThemisBatchCommitSecondaryResult
ThemisCommit
EraseLockRequest
EraseLockResponse
LockExpiredRequest
LockExpiredResponse
*/
package themis
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import Client "github.com/pingcap/go-hbase/proto"
import Cell "github.com/pingcap/go-hbase/proto"
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
type ThemisGetRequest struct {
Get *Client.Get `protobuf:"bytes,1,req,name=get" json:"get,omitempty"`
StartTs *uint64 `protobuf:"varint,2,req,name=startTs" json:"startTs,omitempty"`
IgnoreLock *bool `protobuf:"varint,3,req,name=ignoreLock" json:"ignoreLock,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisGetRequest) Reset() { *m = ThemisGetRequest{} }
func (m *ThemisGetRequest) String() string { return proto.CompactTextString(m) }
func (*ThemisGetRequest) ProtoMessage() {}
func (m *ThemisGetRequest) GetGet() *Client.Get {
if m != nil {
return m.Get
}
return nil
}
func (m *ThemisGetRequest) GetStartTs() uint64 {
if m != nil && m.StartTs != nil {
return *m.StartTs
}
return 0
}
func (m *ThemisGetRequest) GetIgnoreLock() bool {
if m != nil && m.IgnoreLock != nil {
return *m.IgnoreLock
}
return false
}
type ThemisBatchGetRequest struct {
Gets []*Client.Get `protobuf:"bytes,1,rep,name=gets" json:"gets,omitempty"`
StartTs *uint64 `protobuf:"varint,2,req,name=startTs" json:"startTs,omitempty"`
IgnoreLock *bool `protobuf:"varint,3,req,name=ignoreLock" json:"ignoreLock,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisBatchGetRequest) Reset() { *m = ThemisBatchGetRequest{} }
func (m *ThemisBatchGetRequest) String() string { return proto.CompactTextString(m) }
func (*ThemisBatchGetRequest) ProtoMessage() {}
func (m *ThemisBatchGetRequest) GetGets() []*Client.Get {
if m != nil {
return m.Gets
}
return nil
}
func (m *ThemisBatchGetRequest) GetStartTs() uint64 {
if m != nil && m.StartTs != nil {
return *m.StartTs
}
return 0
}
func (m *ThemisBatchGetRequest) GetIgnoreLock() bool {
if m != nil && m.IgnoreLock != nil {
return *m.IgnoreLock
}
return false
}
type ThemisBatchGetResponse struct {
Rs []*Client.Result `protobuf:"bytes,1,rep,name=rs" json:"rs,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisBatchGetResponse) Reset() { *m = ThemisBatchGetResponse{} }
func (m *ThemisBatchGetResponse) String() string { return proto.CompactTextString(m) }
func (*ThemisBatchGetResponse) ProtoMessage() {}
func (m *ThemisBatchGetResponse) GetRs() []*Client.Result {
if m != nil {
return m.Rs
}
return nil
}
type ThemisPrewrite struct {
Row []byte `protobuf:"bytes,1,req,name=row" json:"row,omitempty"`
Mutations []*Cell.Cell `protobuf:"bytes,2,rep,name=mutations" json:"mutations,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisPrewrite) Reset() { *m = ThemisPrewrite{} }
func (m *ThemisPrewrite) String() string { return proto.CompactTextString(m) }
func (*ThemisPrewrite) ProtoMessage() {}
func (m *ThemisPrewrite) GetRow() []byte {
if m != nil {
return m.Row
}
return nil
}
func (m *ThemisPrewrite) GetMutations() []*Cell.Cell {
if m != nil {
return m.Mutations
}
return nil
}
type ThemisPrewriteRequest struct {
ThemisPrewrite *ThemisPrewrite `protobuf:"bytes,1,req,name=themisPrewrite" json:"themisPrewrite,omitempty"`
PrewriteTs *uint64 `protobuf:"varint,2,req,name=prewriteTs" json:"prewriteTs,omitempty"`
SecondaryLock []byte `protobuf:"bytes,3,req,name=secondaryLock" json:"secondaryLock,omitempty"`
PrimaryLock []byte `protobuf:"bytes,4,req,name=primaryLock" json:"primaryLock,omitempty"`
PrimaryIndex *int32 `protobuf:"varint,5,req,name=primaryIndex" json:"primaryIndex,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisPrewriteRequest) Reset() { *m = ThemisPrewriteRequest{} }
func (m *ThemisPrewriteRequest) String() string { return proto.CompactTextString(m) }
func (*ThemisPrewriteRequest) ProtoMessage() {}
func (m *ThemisPrewriteRequest) GetThemisPrewrite() *ThemisPrewrite {
if m != nil {
return m.ThemisPrewrite
}
return nil
}
func (m *ThemisPrewriteRequest) GetPrewriteTs() uint64 {
if m != nil && m.PrewriteTs != nil {
return *m.PrewriteTs
}
return 0
}
func (m *ThemisPrewriteRequest) GetSecondaryLock() []byte {
if m != nil {
return m.SecondaryLock
}
return nil
}
func (m *ThemisPrewriteRequest) GetPrimaryLock() []byte {
if m != nil {
return m.PrimaryLock
}
return nil
}
func (m *ThemisPrewriteRequest) GetPrimaryIndex() int32 {
if m != nil && m.PrimaryIndex != nil {
return *m.PrimaryIndex
}
return 0
}
type ThemisPrewriteResponse struct {
ThemisPrewriteResult *ThemisPrewriteResult `protobuf:"bytes,1,opt,name=themisPrewriteResult" json:"themisPrewriteResult,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisPrewriteResponse) Reset() { *m = ThemisPrewriteResponse{} }
func (m *ThemisPrewriteResponse) String() string { return proto.CompactTextString(m) }
func (*ThemisPrewriteResponse) ProtoMessage() {}
func (m *ThemisPrewriteResponse) GetThemisPrewriteResult() *ThemisPrewriteResult {
if m != nil {
return m.ThemisPrewriteResult
}
return nil
}
type ThemisBatchPrewriteSecondaryRequest struct {
ThemisPrewrite []*ThemisPrewrite `protobuf:"bytes,1,rep,name=themisPrewrite" json:"themisPrewrite,omitempty"`
PrewriteTs *uint64 `protobuf:"varint,2,req,name=prewriteTs" json:"prewriteTs,omitempty"`
SecondaryLock []byte `protobuf:"bytes,3,req,name=secondaryLock" json:"secondaryLock,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisBatchPrewriteSecondaryRequest) Reset() { *m = ThemisBatchPrewriteSecondaryRequest{} }
func (m *ThemisBatchPrewriteSecondaryRequest) String() string { return proto.CompactTextString(m) }
func (*ThemisBatchPrewriteSecondaryRequest) ProtoMessage() {}
func (m *ThemisBatchPrewriteSecondaryRequest) GetThemisPrewrite() []*ThemisPrewrite {
if m != nil {
return m.ThemisPrewrite
}
return nil
}
func (m *ThemisBatchPrewriteSecondaryRequest) GetPrewriteTs() uint64 {
if m != nil && m.PrewriteTs != nil {
return *m.PrewriteTs
}
return 0
}
func (m *ThemisBatchPrewriteSecondaryRequest) GetSecondaryLock() []byte {
if m != nil {
return m.SecondaryLock
}
return nil
}
type ThemisBatchPrewriteSecondaryResponse struct {
ThemisPrewriteResult []*ThemisPrewriteResult `protobuf:"bytes,1,rep,name=themisPrewriteResult" json:"themisPrewriteResult,omitempty"`
RowsNotInRegion [][]byte `protobuf:"bytes,2,rep,name=rowsNotInRegion" json:"rowsNotInRegion,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisBatchPrewriteSecondaryResponse) Reset() { *m = ThemisBatchPrewriteSecondaryResponse{} }
func (m *ThemisBatchPrewriteSecondaryResponse) String() string { return proto.CompactTextString(m) }
func (*ThemisBatchPrewriteSecondaryResponse) ProtoMessage() {}
func (m *ThemisBatchPrewriteSecondaryResponse) GetThemisPrewriteResult() []*ThemisPrewriteResult {
if m != nil {
return m.ThemisPrewriteResult
}
return nil
}
func (m *ThemisBatchPrewriteSecondaryResponse) GetRowsNotInRegion() [][]byte {
if m != nil {
return m.RowsNotInRegion
}
return nil
}
type ThemisPrewriteResult struct {
NewerWriteTs *int64 `protobuf:"varint,1,req,name=newerWriteTs" json:"newerWriteTs,omitempty"`
ExistLock []byte `protobuf:"bytes,2,req,name=existLock" json:"existLock,omitempty"`
Family []byte `protobuf:"bytes,3,req,name=family" json:"family,omitempty"`
Qualifier []byte `protobuf:"bytes,4,req,name=qualifier" json:"qualifier,omitempty"`
LockExpired *bool `protobuf:"varint,5,req,name=lockExpired" json:"lockExpired,omitempty"`
Row []byte `protobuf:"bytes,6,req,name=row" json:"row,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisPrewriteResult) Reset() { *m = ThemisPrewriteResult{} }
func (m *ThemisPrewriteResult) String() string { return proto.CompactTextString(m) }
func (*ThemisPrewriteResult) ProtoMessage() {}
func (m *ThemisPrewriteResult) GetNewerWriteTs() int64 {
if m != nil && m.NewerWriteTs != nil {
return *m.NewerWriteTs
}
return 0
}
func (m *ThemisPrewriteResult) GetExistLock() []byte {
if m != nil {
return m.ExistLock
}
return nil
}
func (m *ThemisPrewriteResult) GetFamily() []byte {
if m != nil {
return m.Family
}
return nil
}
func (m *ThemisPrewriteResult) GetQualifier() []byte {
if m != nil {
return m.Qualifier
}
return nil
}
func (m *ThemisPrewriteResult) GetLockExpired() bool {
if m != nil && m.LockExpired != nil {
return *m.LockExpired
}
return false
}
func (m *ThemisPrewriteResult) GetRow() []byte {
if m != nil {
return m.Row
}
return nil
}
type ThemisCommitRequest struct {
ThemisCommit *ThemisCommit `protobuf:"bytes,1,req,name=themisCommit" json:"themisCommit,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisCommitRequest) Reset() { *m = ThemisCommitRequest{} }
func (m *ThemisCommitRequest) String() string { return proto.CompactTextString(m) }
func (*ThemisCommitRequest) ProtoMessage() {}
func (m *ThemisCommitRequest) GetThemisCommit() *ThemisCommit {
if m != nil {
return m.ThemisCommit
}
return nil
}
type ThemisCommitResponse struct {
Result *bool `protobuf:"varint,1,req,name=result" json:"result,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisCommitResponse) Reset() { *m = ThemisCommitResponse{} }
func (m *ThemisCommitResponse) String() string { return proto.CompactTextString(m) }
func (*ThemisCommitResponse) ProtoMessage() {}
func (m *ThemisCommitResponse) GetResult() bool {
if m != nil && m.Result != nil {
return *m.Result
}
return false
}
type ThemisBatchCommitSecondaryRequest struct {
ThemisCommit []*ThemisCommit `protobuf:"bytes,1,rep,name=themisCommit" json:"themisCommit,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisBatchCommitSecondaryRequest) Reset() { *m = ThemisBatchCommitSecondaryRequest{} }
func (m *ThemisBatchCommitSecondaryRequest) String() string { return proto.CompactTextString(m) }
func (*ThemisBatchCommitSecondaryRequest) ProtoMessage() {}
func (m *ThemisBatchCommitSecondaryRequest) GetThemisCommit() []*ThemisCommit {
if m != nil {
return m.ThemisCommit
}
return nil
}
type ThemisBatchCommitSecondaryResponse struct {
BatchCommitSecondaryResult []*ThemisBatchCommitSecondaryResult `protobuf:"bytes,1,rep,name=batchCommitSecondaryResult" json:"batchCommitSecondaryResult,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisBatchCommitSecondaryResponse) Reset() { *m = ThemisBatchCommitSecondaryResponse{} }
func (m *ThemisBatchCommitSecondaryResponse) String() string { return proto.CompactTextString(m) }
func (*ThemisBatchCommitSecondaryResponse) ProtoMessage() {}
func (m *ThemisBatchCommitSecondaryResponse) GetBatchCommitSecondaryResult() []*ThemisBatchCommitSecondaryResult {
if m != nil {
return m.BatchCommitSecondaryResult
}
return nil
}
type ThemisBatchCommitSecondaryResult struct {
Row []byte `protobuf:"bytes,1,req,name=row" json:"row,omitempty"`
Success *bool `protobuf:"varint,2,req,name=success" json:"success,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisBatchCommitSecondaryResult) Reset() { *m = ThemisBatchCommitSecondaryResult{} }
func (m *ThemisBatchCommitSecondaryResult) String() string { return proto.CompactTextString(m) }
func (*ThemisBatchCommitSecondaryResult) ProtoMessage() {}
func (m *ThemisBatchCommitSecondaryResult) GetRow() []byte {
if m != nil {
return m.Row
}
return nil
}
func (m *ThemisBatchCommitSecondaryResult) GetSuccess() bool {
if m != nil && m.Success != nil {
return *m.Success
}
return false
}
type ThemisCommit struct {
Row []byte `protobuf:"bytes,1,req,name=row" json:"row,omitempty"`
Mutations []*Cell.Cell `protobuf:"bytes,2,rep,name=mutations" json:"mutations,omitempty"`
PrewriteTs *uint64 `protobuf:"varint,3,req,name=prewriteTs" json:"prewriteTs,omitempty"`
CommitTs *uint64 `protobuf:"varint,4,req,name=commitTs" json:"commitTs,omitempty"`
PrimaryIndex *int32 `protobuf:"varint,5,req,name=primaryIndex" json:"primaryIndex,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *ThemisCommit) Reset() { *m = ThemisCommit{} }
func (m *ThemisCommit) String() string { return proto.CompactTextString(m) }
func (*ThemisCommit) ProtoMessage() {}
func (m *ThemisCommit) GetRow() []byte {
if m != nil {
return m.Row
}
return nil
}
func (m *ThemisCommit) GetMutations() []*Cell.Cell {
if m != nil {
return m.Mutations
}
return nil
}
func (m *ThemisCommit) GetPrewriteTs() uint64 {
if m != nil && m.PrewriteTs != nil {
return *m.PrewriteTs
}
return 0
}
func (m *ThemisCommit) GetCommitTs() uint64 {
if m != nil && m.CommitTs != nil {
return *m.CommitTs
}
return 0
}
func (m *ThemisCommit) GetPrimaryIndex() int32 {
if m != nil && m.PrimaryIndex != nil {
return *m.PrimaryIndex
}
return 0
}
type EraseLockRequest struct {
Row []byte `protobuf:"bytes,1,req,name=row" json:"row,omitempty"`
Family []byte `protobuf:"bytes,2,req,name=family" json:"family,omitempty"`
Qualifier []byte `protobuf:"bytes,3,req,name=qualifier" json:"qualifier,omitempty"`
PrewriteTs *uint64 `protobuf:"varint,4,req,name=prewriteTs" json:"prewriteTs,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *EraseLockRequest) Reset() { *m = EraseLockRequest{} }
func (m *EraseLockRequest) String() string { return proto.CompactTextString(m) }
func (*EraseLockRequest) ProtoMessage() {}
func (m *EraseLockRequest) GetRow() []byte {
if m != nil {
return m.Row
}
return nil
}
func (m *EraseLockRequest) GetFamily() []byte {
if m != nil {
return m.Family
}
return nil
}
func (m *EraseLockRequest) GetQualifier() []byte {
if m != nil {
return m.Qualifier
}
return nil
}
func (m *EraseLockRequest) GetPrewriteTs() uint64 {
if m != nil && m.PrewriteTs != nil {
return *m.PrewriteTs
}
return 0
}
type EraseLockResponse struct {
Lock []byte `protobuf:"bytes,1,opt,name=lock" json:"lock,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *EraseLockResponse) Reset() { *m = EraseLockResponse{} }
func (m *EraseLockResponse) String() string { return proto.CompactTextString(m) }
func (*EraseLockResponse) ProtoMessage() {}
func (m *EraseLockResponse) GetLock() []byte {
if m != nil {
return m.Lock
}
return nil
}
type LockExpiredRequest struct {
Timestamp *uint64 `protobuf:"varint,1,req,name=timestamp" json:"timestamp,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *LockExpiredRequest) Reset() { *m = LockExpiredRequest{} }
func (m *LockExpiredRequest) String() string { return proto.CompactTextString(m) }
func (*LockExpiredRequest) ProtoMessage() {}
func (m *LockExpiredRequest) GetTimestamp() uint64 {
if m != nil && m.Timestamp != nil {
return *m.Timestamp
}
return 0
}
type LockExpiredResponse struct {
Expired *bool `protobuf:"varint,1,req,name=expired" json:"expired,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (m *LockExpiredResponse) Reset() { *m = LockExpiredResponse{} }
func (m *LockExpiredResponse) String() string { return proto.CompactTextString(m) }
func (*LockExpiredResponse) ProtoMessage() {}
func (m *LockExpiredResponse) GetExpired() bool {
if m != nil && m.Expired != nil {
return *m.Expired
}
return false
}

20
vendor/github.com/pingcap/go-themis/consts.go generated vendored Normal file
View file

@ -0,0 +1,20 @@
package themis
import "strings"
var (
PutFamilyName = []byte("#p")
DelFamilyName = []byte("#d")
LockFamilyName = []byte("L")
)
const (
ThemisServiceName string = "ThemisService"
)
func isWrongRegionErr(err error) bool {
if err != nil {
return strings.Contains(err.Error(), "org.apache.hadoop.hbase.regionserver.WrongRegionException")
}
return false
}

58
vendor/github.com/pingcap/go-themis/lock.go generated vendored Normal file
View file

@ -0,0 +1,58 @@
package themis
import "github.com/pingcap/go-hbase"
// LockRole is the role of lock
type LockRole int
func (l LockRole) String() string {
if l == RolePrimary {
return "primary"
}
return "secondary"
}
const (
// RolePrimary means this row is primary
RolePrimary LockRole = iota
// RoleSecondary means this row is secondary
RoleSecondary
)
type Lock interface {
// SetCoordinate sets lock's coordinate
SetCoordinate(c *hbase.ColumnCoordinate)
// Coordinate returns the lock's coordinate
Coordinate() *hbase.ColumnCoordinate
// Timestamp returns startTs of the transction which owned this lock
Timestamp() uint64
// SetExpired sets the lock's expired status.
SetExpired(b bool)
// IsExpired returns if lock is expired.
IsExpired() bool
// Type returns the lock's type, Put or Delete
Type() hbase.Type
// Role returns LockRole, primary or secondary
Role() LockRole
// not used now
Context() interface{}
// valid only Role == Primary
Secondaries() []Lock
// Primary returns the primary lock of this lock
Primary() Lock
// Encode encodes the lock to byte slice
Encode() []byte
}
type LockManager interface {
// CleanLock if clean lock success, first return value is transction's commit
// timestamp, otherwise, the second return value is transction's primary
// lock.
CleanLock(c *hbase.ColumnCoordinate, prewriteTs uint64) (uint64, Lock, error)
// EraseLockAndData removes lock and data.
EraseLockAndData(c *hbase.ColumnCoordinate, prewriteTs uint64) error
// GetCommitTimestamp returns a committed transction's commit timestamp.
GetCommitTimestamp(c *hbase.ColumnCoordinate, prewriteTs uint64) (uint64, error)
// [startTs, endTs]
IsLockExists(c *hbase.ColumnCoordinate, startTs, endTs uint64) (bool, error)
}

233
vendor/github.com/pingcap/go-themis/mutation_cache.go generated vendored Normal file
View file

@ -0,0 +1,233 @@
package themis
import (
"fmt"
"sort"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase"
"github.com/pingcap/go-hbase/proto"
)
type mutationValuePair struct {
typ hbase.Type
value []byte
}
func (mp *mutationValuePair) String() string {
return fmt.Sprintf("type: %d value: %s", mp.typ, mp.value)
}
type columnMutation struct {
*hbase.Column
*mutationValuePair
}
func getEntriesFromDel(p *hbase.Delete) ([]*columnMutation, error) {
errMsg := "must set at least one column for themis delete"
if len(p.FamilyQuals) == 0 {
return nil, errors.New(errMsg)
}
var ret []*columnMutation
for f, _ := range p.Families {
quilifiers := p.FamilyQuals[f]
if len(quilifiers) == 0 {
return nil, errors.New(errMsg)
}
for q, _ := range quilifiers {
mutation := &columnMutation{
Column: &hbase.Column{
Family: []byte(f),
Qual: []byte(q),
},
mutationValuePair: &mutationValuePair{
typ: hbase.TypeDeleteColumn,
},
}
ret = append(ret, mutation)
}
}
return ret, nil
}
func getEntriesFromPut(p *hbase.Put) []*columnMutation {
var ret []*columnMutation
for i, f := range p.Families {
qualifiers := p.Qualifiers[i]
for j, q := range qualifiers {
mutation := &columnMutation{
Column: &hbase.Column{
Family: f,
Qual: q,
},
mutationValuePair: &mutationValuePair{
typ: hbase.TypePut,
value: p.Values[i][j],
},
}
ret = append(ret, mutation)
}
}
return ret
}
func (cm *columnMutation) toCell() *proto.Cell {
ret := &proto.Cell{
Family: cm.Family,
Qualifier: cm.Qual,
Value: cm.value,
}
if cm.typ == hbase.TypePut { // put
ret.CellType = proto.CellType_PUT.Enum()
} else if cm.typ == hbase.TypeMinimum { // onlyLock
ret.CellType = proto.CellType_MINIMUM.Enum()
} else { // delete, themis delete API only support delete column
ret.CellType = proto.CellType_DELETE_COLUMN.Enum()
}
return ret
}
type rowMutation struct {
tbl []byte
row []byte
// mutations := { 'cf:col' => mutationValuePair }
mutations map[string]*mutationValuePair
}
func (r *rowMutation) getColumns() []hbase.Column {
var ret []hbase.Column
for k, _ := range r.mutations {
c := &hbase.Column{}
// TODO: handle error, now just ignore
if err := c.ParseFromString(k); err != nil {
log.Warnf("parse from string error, column: %s, mutation: %s, error: %v", c, k, err)
}
ret = append(ret, *c)
}
return ret
}
func (r *rowMutation) getSize() int {
return len(r.mutations)
}
func (r *rowMutation) getType(c hbase.Column) hbase.Type {
p, ok := r.mutations[c.String()]
if !ok {
return hbase.TypeMinimum
}
return p.typ
}
func newRowMutation(tbl, row []byte) *rowMutation {
return &rowMutation{
tbl: tbl,
row: row,
mutations: map[string]*mutationValuePair{},
}
}
func (r *rowMutation) addMutation(c *hbase.Column, typ hbase.Type, val []byte, onlyLock bool) {
// 3 scene: put, delete, onlyLock
// if it is onlyLock scene, then has not data modify, when has contained the qualifier, can't replace exist value,
// becuase put or delete operation has add mutation
if onlyLock && r.mutations[c.String()] != nil {
return
}
r.mutations[c.String()] = &mutationValuePair{
typ: typ,
value: val,
}
}
func (r *rowMutation) mutationList(withValue bool) []*columnMutation {
var ret []*columnMutation
var keys []string
for k, _ := range r.mutations {
keys = append(keys, k)
}
sort.Strings(keys)
for _, k := range keys {
v := &mutationValuePair{
typ: r.mutations[k].typ,
}
if withValue {
v.value = r.mutations[k].value
}
c := &hbase.Column{}
// TODO: handle error, now just ignore
if err := c.ParseFromString(k); err != nil {
log.Warnf("parse from string error, column: %s, mutation: %s, error: %v", c, k, err)
}
ret = append(ret, &columnMutation{
Column: c,
mutationValuePair: v,
})
}
return ret
}
type columnMutationCache struct {
// mutations => {table => { rowKey => row mutations } }
mutations map[string]map[string]*rowMutation
}
func newColumnMutationCache() *columnMutationCache {
return &columnMutationCache{
mutations: map[string]map[string]*rowMutation{},
}
}
func (c *columnMutationCache) addMutation(tbl []byte, row []byte, col *hbase.Column, t hbase.Type, v []byte, onlyLock bool) {
tblRowMutations, ok := c.mutations[string(tbl)]
if !ok {
// create table mutation map
tblRowMutations = map[string]*rowMutation{}
c.mutations[string(tbl)] = tblRowMutations
}
rowMutations, ok := tblRowMutations[string(row)]
if !ok {
// create row mutation map
rowMutations = newRowMutation(tbl, row)
tblRowMutations[string(row)] = rowMutations
}
rowMutations.addMutation(col, t, v, onlyLock)
}
func (c *columnMutationCache) getMutation(cc *hbase.ColumnCoordinate) *mutationValuePair {
t, ok := c.mutations[string(cc.Table)]
if !ok {
return nil
}
rowMutation, ok := t[string(cc.Row)]
if !ok {
return nil
}
p, ok := rowMutation.mutations[cc.GetColumn().String()]
if !ok {
return nil
}
return p
}
func (c *columnMutationCache) getRowCount() int {
ret := 0
for _, v := range c.mutations {
ret += len(v)
}
return ret
}
func (c *columnMutationCache) getMutationCount() int {
ret := 0
for _, v := range c.mutations {
for _, vv := range v {
ret += len(vv.mutationList(false))
}
}
return ret
}

6
vendor/github.com/pingcap/go-themis/oracle/oracle.go generated vendored Normal file
View file

@ -0,0 +1,6 @@
package oracle
type Oracle interface {
GetTimestamp() (uint64, error)
IsExpired(lockTimestamp uint64, TTL uint64) bool
}

View file

@ -0,0 +1,42 @@
package oracles
import (
"sync"
"time"
"github.com/pingcap/go-themis/oracle"
)
const epochShiftBits = 18
var _ oracle.Oracle = &localOracle{}
type localOracle struct {
mu sync.Mutex
lastTimeStampTs int64
n int64
}
// NewLocalOracle creates an Oracle that use local time as data source.
func NewLocalOracle() oracle.Oracle {
return &localOracle{}
}
func (l *localOracle) IsExpired(lockTs uint64, TTL uint64) bool {
beginMs := lockTs >> epochShiftBits
return uint64(time.Now().UnixNano()/int64(time.Millisecond)) >= (beginMs + TTL)
}
func (l *localOracle) GetTimestamp() (uint64, error) {
l.mu.Lock()
defer l.mu.Unlock()
ts := (time.Now().UnixNano() / int64(time.Millisecond)) << epochShiftBits
if l.lastTimeStampTs == ts {
l.n++
return uint64(ts + l.n), nil
} else {
l.lastTimeStampTs = ts
l.n = 0
}
return uint64(ts), nil
}

View file

@ -0,0 +1,48 @@
package oracles
import (
"time"
"github.com/juju/errors"
"github.com/ngaut/tso/client"
"github.com/pingcap/go-themis/oracle"
)
const maxRetryCnt = 3
var _ oracle.Oracle = &remoteOracle{}
// remoteOracle is an oracle that use a remote data source.
type remoteOracle struct {
c *client.Client
}
// NewRemoteOracle creates an oracle that use a remote data source.
// Refer https://github.com/ngaut/tso for more details.
func NewRemoteOracle(zks, path string) oracle.Oracle {
return &remoteOracle{
c: client.NewClient(&client.Conf{
ZKAddr: zks,
RootPath: path,
}),
}
}
func (t *remoteOracle) IsExpired(lockTs uint64, TTL uint64) bool {
beginMs := lockTs >> epochShiftBits
// TODO records the local wall time when getting beginMs from TSO
return uint64(time.Now().UnixNano()/int64(time.Millisecond)) >= (beginMs + TTL)
}
// GetTimestamp gets timestamp from remote data source.
func (t *remoteOracle) GetTimestamp() (uint64, error) {
var err error
for i := 0; i < maxRetryCnt; i++ {
ts, e := t.c.GoGetTimestamp().GetTS()
if e == nil {
return uint64((ts.Physical << epochShiftBits) + ts.Logical), nil
}
err = errors.Trace(e)
}
return 0, err
}

133
vendor/github.com/pingcap/go-themis/themis_lock.go generated vendored Normal file
View file

@ -0,0 +1,133 @@
package themis
import (
"bytes"
"encoding/binary"
"io"
"github.com/juju/errors"
"github.com/pingcap/go-hbase"
"github.com/pingcap/go-hbase/iohelper"
)
var (
_ Lock = (*themisPrimaryLock)(nil)
_ Lock = (*themisSecondaryLock)(nil)
)
type themisLock struct {
// lock coordinate, table, row, cf, q
coordinate *hbase.ColumnCoordinate
// lock type: put/delete/minimal(lock only)
typ hbase.Type
// prewrite ts
ts uint64
// not used, for alignment
wallTs uint64
// not used, for alignment
clientAddr string
expired bool
}
func (l *themisLock) Timestamp() uint64 {
return l.ts
}
func (l *themisLock) IsExpired() bool {
return l.expired
}
func (l *themisLock) SetExpired(b bool) {
l.expired = b
}
func (l *themisLock) SetCoordinate(c *hbase.ColumnCoordinate) {
l.coordinate = c
}
func (l *themisLock) Coordinate() *hbase.ColumnCoordinate {
return l.coordinate
}
func (l *themisLock) Context() interface{} {
return nil
}
func (l *themisLock) Type() hbase.Type {
return l.typ
}
func (l *themisLock) write(w io.Writer) {
binary.Write(w, binary.BigEndian, byte(l.typ))
binary.Write(w, binary.BigEndian, int64(l.ts))
// write client addr
iohelper.WriteVarBytes(w, []byte(l.clientAddr))
binary.Write(w, binary.BigEndian, int64(l.wallTs))
}
func (l *themisLock) parse(r iohelper.ByteMultiReader) error {
// read type
var typ uint8
err := binary.Read(r, binary.BigEndian, &typ)
if err != nil {
return errors.Trace(err)
}
l.typ = hbase.Type(typ)
// read ts
var ts int64
err = binary.Read(r, binary.BigEndian, &ts)
if err != nil {
return errors.Trace(err)
}
l.ts = uint64(ts)
// read client addr
sz, err := binary.ReadUvarint(r)
if err != nil {
return errors.Trace(err)
}
addr := make([]byte, sz)
r.Read(addr)
l.clientAddr = string(addr)
// read wall time
var wallTs int64
err = binary.Read(r, binary.BigEndian, &wallTs)
if err != nil {
return errors.Trace(err)
}
l.wallTs = uint64(wallTs)
return nil
}
func parseLockFromBytes(b []byte) (Lock, error) {
buf := bytes.NewBuffer(b)
var isPrimary uint8
err := binary.Read(buf, binary.BigEndian, &isPrimary)
if err != nil {
return nil, errors.Trace(err)
}
var ret Lock
if isPrimary == 1 {
l := newThemisPrimaryLock()
err = l.parse(buf)
ret = l
} else {
l := newThemisSecondaryLock()
err = l.parse(buf)
ret = l
}
if err != nil {
return nil, errors.Trace(err)
}
return ret, nil
}
func isLockResult(r *hbase.ResultRow) bool {
return len(r.SortedColumns) > 0 && isLockColumn(r.SortedColumns[0].Column)
}
func isLockColumn(c hbase.Column) bool {
return bytes.Compare(c.Family, LockFamilyName) == 0
}

View file

@ -0,0 +1,147 @@
package themis
import (
"bytes"
"encoding/binary"
"math"
"strings"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase"
)
var _ LockManager = (*themisLockManager)(nil)
type themisLockManager struct {
rpc *themisRPC
hbaseClient hbase.HBaseClient
}
func newThemisLockManager(rpc *themisRPC, hbaseCli hbase.HBaseClient) LockManager {
return &themisLockManager{
rpc: rpc,
hbaseClient: hbaseCli,
}
}
func getDataColFromMetaCol(lockOrWriteCol hbase.Column) hbase.Column {
// get data column from lock column
// key is like => L:family#qual, #p:family#qual
parts := strings.Split(string(lockOrWriteCol.Qual), "#")
if len(parts) != 2 {
return lockOrWriteCol
}
c := hbase.Column{
Family: []byte(parts[0]),
Qual: []byte(parts[1]),
}
return c
}
func getLocksFromResults(tbl []byte, lockKvs []*hbase.Kv, client *themisRPC) ([]Lock, error) {
var locks []Lock
for _, kv := range lockKvs {
col := &hbase.ColumnCoordinate{
Table: tbl,
Row: kv.Row,
Column: hbase.Column{
Family: kv.Family,
Qual: kv.Qual,
},
}
if !isLockColumn(col.Column) {
return nil, errors.New("invalid lock")
}
l, err := parseLockFromBytes(kv.Value)
if err != nil {
return nil, errors.Trace(err)
}
cc := &hbase.ColumnCoordinate{
Table: tbl,
Row: kv.Row,
Column: getDataColFromMetaCol(col.Column),
}
l.SetCoordinate(cc)
client.checkAndSetLockIsExpired(l)
locks = append(locks, l)
}
return locks, nil
}
func (m *themisLockManager) IsLockExists(cc *hbase.ColumnCoordinate, startTs, endTs uint64) (bool, error) {
get := hbase.NewGet(cc.Row)
get.AddTimeRange(startTs, endTs+1)
get.AddStringColumn(string(LockFamilyName), string(cc.Family)+"#"+string(cc.Qual))
// check if lock exists
rs, err := m.hbaseClient.Get(string(cc.Table), get)
if err != nil {
return false, errors.Trace(err)
}
// primary lock has been released
if rs == nil {
return false, nil
}
return true, nil
}
func (m *themisLockManager) GetCommitTimestamp(cc *hbase.ColumnCoordinate, prewriteTs uint64) (uint64, error) {
g := hbase.NewGet(cc.Row)
// add put write column
qual := string(cc.Family) + "#" + string(cc.Qual)
g.AddStringColumn("#p", qual)
// add del write column
g.AddStringColumn("#d", qual)
// time range => [ours startTs, +Inf)
g.AddTimeRange(prewriteTs, math.MaxInt64)
g.SetMaxVersion(math.MaxInt32)
r, err := m.hbaseClient.Get(string(cc.Table), g)
if err != nil {
return 0, errors.Trace(err)
}
// may delete by other client
if r == nil {
return 0, nil
}
for _, kv := range r.SortedColumns {
for commitTs, val := range kv.Values {
var ts uint64
binary.Read(bytes.NewBuffer(val), binary.BigEndian, &ts)
if ts == prewriteTs {
// get this commit's commitTs
return commitTs, nil
}
}
}
// no such transction
return 0, nil
}
func (m *themisLockManager) CleanLock(cc *hbase.ColumnCoordinate, prewriteTs uint64) (uint64, Lock, error) {
l, err := m.rpc.getLockAndErase(cc, prewriteTs)
if err != nil {
return 0, nil, errors.Trace(err)
}
pl, _ := l.(*themisPrimaryLock)
// if primary lock is nil, means someothers have already committed
if pl == nil {
commitTs, err := m.GetCommitTimestamp(cc, prewriteTs)
if err != nil {
return 0, nil, errors.Trace(err)
}
return commitTs, nil, nil
}
return 0, pl, nil
}
func (m *themisLockManager) EraseLockAndData(cc *hbase.ColumnCoordinate, prewriteTs uint64) error {
log.Debugf("erase row=%q txn=%d", cc.Row, prewriteTs)
d := hbase.NewDelete(cc.Row)
d.AddColumnWithTimestamp(LockFamilyName, []byte(string(cc.Family)+"#"+string(cc.Qual)), prewriteTs)
d.AddColumnWithTimestamp(cc.Family, cc.Qual, prewriteTs)
ok, err := m.hbaseClient.Delete(string(cc.Table), d)
if !ok {
log.Error(err)
}
return errors.Trace(err)
}

View file

@ -0,0 +1,112 @@
package themis
import (
"bytes"
"encoding/binary"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase"
"github.com/pingcap/go-hbase/iohelper"
)
type themisPrimaryLock struct {
*themisLock
// {coordinate => type}
secondaries map[string]hbase.Type
}
func newThemisPrimaryLock() *themisPrimaryLock {
return &themisPrimaryLock{
themisLock: &themisLock{
clientAddr: "null",
},
secondaries: map[string]hbase.Type{},
}
}
func (l *themisPrimaryLock) Primary() Lock {
return l
}
func (l *themisPrimaryLock) Secondaries() []Lock {
var slocks []Lock
for k, v := range l.secondaries {
c := &hbase.ColumnCoordinate{}
// TODO: handle error, now just ignore
if err := c.ParseFromString(k); err != nil {
log.Warnf("parse from string error, column coordinate: %s, secondary: %s, error: %v", c, k, err)
continue
}
slock := newThemisSecondaryLock()
slock.primaryCoordinate = l.coordinate
slock.coordinate = c
slock.ts = l.ts
slock.typ = v
slocks = append(slocks, slock)
}
return slocks
}
func (l *themisPrimaryLock) Encode() []byte {
buf := bytes.NewBuffer(nil)
// set is primary
binary.Write(buf, binary.BigEndian, uint8(1))
l.themisLock.write(buf)
// write secondaries
binary.Write(buf, binary.BigEndian, int32(len(l.secondaries)))
for k, v := range l.secondaries {
c := &hbase.ColumnCoordinate{}
// TODO: handle error, now just log
if err := c.ParseFromString(k); err != nil {
log.Warnf("parse from string error, column coordinate: %s, secondary: %s, error: %v", c, k, err)
}
// TODO: handle error, now just log
if err := c.Write(buf); err != nil {
log.Warnf("write error, column coordinate: %s, buf: %s, error: %v", c, buf, err)
}
buf.WriteByte(uint8(v))
}
return buf.Bytes()
}
func (l *themisPrimaryLock) IsExpired() bool {
return l.themisLock.expired
}
func (l *themisPrimaryLock) getSecondaryColumnType(c *hbase.ColumnCoordinate) hbase.Type {
v, ok := l.secondaries[c.String()]
if !ok {
return hbase.TypeMinimum
}
return v
}
func (l *themisPrimaryLock) Role() LockRole {
return RolePrimary
}
func (l *themisPrimaryLock) addSecondary(col *hbase.ColumnCoordinate, t hbase.Type) {
l.secondaries[col.String()] = t
}
func (l *themisPrimaryLock) parse(buf iohelper.ByteMultiReader) error {
l.themisLock.parse(buf)
var sz int32
err := binary.Read(buf, binary.BigEndian, &sz)
if err != nil {
return errors.Trace(err)
}
for i := 0; i < int(sz); i++ {
c := &hbase.ColumnCoordinate{}
c.ParseField(buf)
b, err := buf.ReadByte()
if err != nil {
return errors.Trace(err)
}
t := hbase.Type(b)
l.addSecondary(c, t)
}
return nil
}

368
vendor/github.com/pingcap/go-themis/themis_rpc.go generated vendored Normal file
View file

@ -0,0 +1,368 @@
package themis
import (
"fmt"
"runtime/debug"
pb "github.com/golang/protobuf/proto"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase"
"github.com/pingcap/go-hbase/proto"
"github.com/pingcap/go-themis/oracle"
)
func newThemisRPC(client hbase.HBaseClient, oracle oracle.Oracle, conf TxnConfig) *themisRPC {
return &themisRPC{
client: client,
conf: conf,
oracle: oracle,
}
}
type themisRPC struct {
client hbase.HBaseClient
conf TxnConfig
oracle oracle.Oracle
}
func (rpc *themisRPC) call(methodName string, tbl, row []byte, req pb.Message, resp pb.Message) error {
param, _ := pb.Marshal(req)
call := &hbase.CoprocessorServiceCall{
Row: row,
ServiceName: ThemisServiceName,
MethodName: methodName,
RequestParam: param,
}
r, err := rpc.client.ServiceCall(string(tbl), call)
if err != nil {
return errors.Trace(err)
}
err = pb.Unmarshal(r.GetValue().GetValue(), resp)
if err != nil {
return errors.Trace(err)
}
return nil
}
func (rpc *themisRPC) checkAndSetLockIsExpired(lock Lock) (bool, error) {
expired := rpc.oracle.IsExpired(lock.Timestamp(), rpc.conf.TTLInMs)
lock.SetExpired(expired)
return expired, nil
}
func (rpc *themisRPC) themisGet(tbl []byte, g *hbase.Get, startTs uint64, ignoreLock bool) (*hbase.ResultRow, error) {
req := &ThemisGetRequest{
Get: g.ToProto().(*proto.Get),
StartTs: pb.Uint64(startTs),
IgnoreLock: pb.Bool(ignoreLock),
}
var resp proto.Result
err := rpc.call("themisGet", tbl, g.Row, req, &resp)
if err != nil {
return nil, errors.Trace(err)
}
return hbase.NewResultRow(&resp), nil
}
func (rpc *themisRPC) themisBatchGet(tbl []byte, gets []*hbase.Get, startTs uint64, ignoreLock bool) ([]*hbase.ResultRow, error) {
var protoGets []*proto.Get
for _, g := range gets {
protoGets = append(protoGets, g.ToProto().(*proto.Get))
}
req := &ThemisBatchGetRequest{
Gets: protoGets,
StartTs: pb.Uint64(startTs),
IgnoreLock: pb.Bool(ignoreLock),
}
var resp ThemisBatchGetResponse
err := rpc.call("themisBatchGet", tbl, gets[0].Row, req, &resp)
if err != nil {
return nil, errors.Trace(err)
}
var results []*hbase.ResultRow
for _, rs := range resp.GetRs() {
results = append(results, hbase.NewResultRow(rs))
}
return results, nil
}
func (rpc *themisRPC) prewriteRow(tbl []byte, row []byte, mutations []*columnMutation, prewriteTs uint64, primaryLockBytes []byte, secondaryLockBytes []byte, primaryOffset int) (Lock, error) {
var cells []*proto.Cell
request := &ThemisPrewriteRequest{
PrewriteTs: pb.Uint64(prewriteTs),
PrimaryLock: primaryLockBytes,
SecondaryLock: secondaryLockBytes,
PrimaryIndex: pb.Int(primaryOffset),
}
request.ThemisPrewrite = &ThemisPrewrite{
Row: row,
}
if primaryLockBytes == nil {
request.PrimaryLock = []byte("")
}
if secondaryLockBytes == nil {
request.SecondaryLock = []byte("")
}
for _, m := range mutations {
cells = append(cells, m.toCell())
}
request.ThemisPrewrite.Mutations = cells
var res ThemisPrewriteResponse
err := rpc.call("prewriteRow", tbl, row, request, &res)
if err != nil {
return nil, errors.Trace(err)
}
b := res.ThemisPrewriteResult
if b == nil {
// if lock is empty, means we got the lock, otherwise some one else had
// locked this row, and the lock should return in rpc result
return nil, nil
}
// Oops, someone else have already locked this row.
commitTs := b.GetNewerWriteTs()
if commitTs != 0 {
log.Errorf("write conflict, encounter write with larger timestamp than prewriteTs=%d, commitTs=%d, row=%s", prewriteTs, commitTs, string(row))
return nil, ErrRetryable
}
l, err := parseLockFromBytes(b.ExistLock)
if err != nil {
return nil, errors.Trace(err)
}
col := &hbase.ColumnCoordinate{
Table: tbl,
Row: row,
Column: hbase.Column{
Family: b.Family,
Qual: b.Qualifier,
},
}
l.SetCoordinate(col)
return l, nil
}
func (rpc *themisRPC) isLockExpired(tbl, row []byte, ts uint64) (bool, error) {
req := &LockExpiredRequest{
Timestamp: pb.Uint64(ts),
}
var res LockExpiredResponse
if row == nil {
debug.PrintStack()
}
err := rpc.call("isLockExpired", tbl, row, req, &res)
if err != nil {
return false, errors.Trace(err)
}
return res.GetExpired(), nil
}
func (rpc *themisRPC) getLockAndErase(cc *hbase.ColumnCoordinate, prewriteTs uint64) (Lock, error) {
req := &EraseLockRequest{
Row: cc.Row,
Family: cc.Column.Family,
Qualifier: cc.Column.Qual,
PrewriteTs: pb.Uint64(prewriteTs),
}
var res EraseLockResponse
err := rpc.call("getLockAndErase", cc.Table, cc.Row, req, &res)
if err != nil {
return nil, errors.Trace(err)
}
b := res.GetLock()
if len(b) == 0 {
return nil, nil
}
return parseLockFromBytes(b)
}
func (rpc *themisRPC) commitRow(tbl, row []byte, mutations []*columnMutation,
prewriteTs, commitTs uint64, primaryOffset int) error {
req := &ThemisCommitRequest{}
req.ThemisCommit = &ThemisCommit{
Row: row,
PrewriteTs: pb.Uint64(prewriteTs),
CommitTs: pb.Uint64(commitTs),
PrimaryIndex: pb.Int(primaryOffset),
}
for _, m := range mutations {
req.ThemisCommit.Mutations = append(req.ThemisCommit.Mutations, m.toCell())
}
var res ThemisCommitResponse
err := rpc.call("commitRow", tbl, row, req, &res)
if err != nil {
return errors.Trace(err)
}
ok := res.GetResult()
if !ok {
if primaryOffset == -1 {
return errors.Errorf("commit secondary failed, tbl: %s row: %q ts: %d", tbl, row, commitTs)
}
return errors.Errorf("commit primary failed, tbl: %s row: %q ts: %d", tbl, row, commitTs)
}
return nil
}
func (rpc *themisRPC) batchCommitSecondaryRows(tbl []byte, rowMs map[string]*rowMutation, prewriteTs, commitTs uint64) error {
req := &ThemisBatchCommitSecondaryRequest{}
i := 0
var lastRow []byte
req.ThemisCommit = make([]*ThemisCommit, len(rowMs))
for row, rowM := range rowMs {
var cells []*proto.Cell
for col, m := range rowM.mutations {
cells = append(cells, toCellFromRowM(col, m))
}
req.ThemisCommit[i] = &ThemisCommit{
Row: []byte(row),
Mutations: cells,
PrewriteTs: pb.Uint64(prewriteTs),
CommitTs: pb.Uint64(commitTs),
PrimaryIndex: pb.Int(-1),
}
i++
lastRow = []byte(row)
}
var res ThemisBatchCommitSecondaryResponse
err := rpc.call("batchCommitSecondaryRows", tbl, lastRow, req, &res)
if err != nil {
return errors.Trace(err)
}
log.Info("call batch commit secondary rows", len(req.ThemisCommit))
cResult := res.BatchCommitSecondaryResult
if cResult != nil && len(cResult) > 0 {
errorInfo := "commit failed, tbl:" + string(tbl)
for _, r := range cResult {
errorInfo += (" row:" + string(r.Row))
}
return errors.New(fmt.Sprintf("%s, commitTs:%d", errorInfo, commitTs))
}
return nil
}
func (rpc *themisRPC) commitSecondaryRow(tbl, row []byte, mutations []*columnMutation,
prewriteTs, commitTs uint64) error {
return rpc.commitRow(tbl, row, mutations, prewriteTs, commitTs, -1)
}
func (rpc *themisRPC) prewriteSecondaryRow(tbl, row []byte,
mutations []*columnMutation, prewriteTs uint64,
secondaryLockBytes []byte) (Lock, error) {
return rpc.prewriteRow(tbl, row, mutations, prewriteTs, nil, secondaryLockBytes, -1)
}
func (rpc *themisRPC) batchPrewriteSecondaryRows(tbl []byte, rowMs map[string]*rowMutation, prewriteTs uint64, secondaryLockBytes []byte) (map[string]Lock, error) {
request := &ThemisBatchPrewriteSecondaryRequest{
PrewriteTs: pb.Uint64(prewriteTs),
SecondaryLock: secondaryLockBytes,
}
request.ThemisPrewrite = make([]*ThemisPrewrite, len(rowMs))
if secondaryLockBytes == nil {
secondaryLockBytes = []byte("")
}
i := 0
var lastRow []byte
for row, rowM := range rowMs {
var cells []*proto.Cell
for col, m := range rowM.mutations {
cells = append(cells, toCellFromRowM(col, m))
}
request.ThemisPrewrite[i] = &ThemisPrewrite{
Row: []byte(row),
Mutations: cells,
}
i++
lastRow = []byte(row)
}
var res ThemisBatchPrewriteSecondaryResponse
err := rpc.call("batchPrewriteSecondaryRows", tbl, lastRow, request, &res)
if err != nil {
return nil, errors.Trace(err)
}
//Perhaps, part row has not in a region, sample : when region split, then need try
lockMap := make(map[string]Lock)
if res.RowsNotInRegion != nil && len(res.RowsNotInRegion) > 0 {
for _, r := range res.RowsNotInRegion {
tl, err := rpc.prewriteSecondaryRow(tbl, r, rowMs[string(r)].mutationList(true), prewriteTs, secondaryLockBytes)
if err != nil {
return nil, errors.Trace(err)
}
if tl != nil {
lockMap[string(r)] = tl
}
}
}
b := res.ThemisPrewriteResult
if b != nil && len(b) > 0 {
for _, pResult := range b {
lock, err := judgePerwriteResultRow(pResult, tbl, prewriteTs, pResult.Row)
if err != nil {
return nil, errors.Trace(err)
}
if lock != nil {
lockMap[string(pResult.Row)] = lock
}
}
}
return lockMap, nil
}
func judgePerwriteResultRow(pResult *ThemisPrewriteResult, tbl []byte, prewriteTs uint64, row []byte) (Lock, error) {
// Oops, someone else have already locked this row.
newerTs := pResult.GetNewerWriteTs()
if newerTs != 0 {
return nil, ErrRetryable
}
l, err := parseLockFromBytes(pResult.ExistLock)
if err != nil {
return nil, errors.Trace(err)
}
col := &hbase.ColumnCoordinate{
Table: tbl,
Row: row,
Column: hbase.Column{
Family: pResult.Family,
Qual: pResult.Qualifier,
},
}
l.SetCoordinate(col)
return l, nil
}
func toCellFromRowM(col string, cvPair *mutationValuePair) *proto.Cell {
c := &hbase.Column{}
// TODO: handle error, now just log
if err := c.ParseFromString(col); err != nil {
log.Warnf("parse from string error, column: %s, col: %s, error: %v", c, col, err)
}
ret := &proto.Cell{
Family: c.Family,
Qualifier: c.Qual,
Value: cvPair.value,
}
if cvPair.typ == hbase.TypePut { // put
ret.CellType = proto.CellType_PUT.Enum()
} else if cvPair.typ == hbase.TypeMinimum { // onlyLock
ret.CellType = proto.CellType_MINIMUM.Enum()
} else { // delete, themis delete API only support delete column
ret.CellType = proto.CellType_DELETE_COLUMN.Enum()
}
return ret
}

85
vendor/github.com/pingcap/go-themis/themis_scan.go generated vendored Normal file
View file

@ -0,0 +1,85 @@
package themis
import (
"bytes"
"encoding/binary"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase"
)
type ThemisScanner struct {
scan *hbase.Scan
txn *themisTxn
tbl []byte
}
func newThemisScanner(tbl []byte, txn *themisTxn, batchSize int, c hbase.HBaseClient) *ThemisScanner {
s := hbase.NewScan(tbl, batchSize, c)
// add start ts
b := bytes.NewBuffer(nil)
binary.Write(b, binary.BigEndian, txn.startTs)
s.AddAttr("_themisTransationStartTs_", b.Bytes())
return &ThemisScanner{
scan: s,
txn: txn,
tbl: tbl,
}
}
func (s *ThemisScanner) setStartRow(start []byte) {
s.scan.StartRow = start
}
func (s *ThemisScanner) setStopRow(stop []byte) {
s.scan.StopRow = stop
}
func (s *ThemisScanner) SetTimeRange(tsRangeFrom uint64, tsRangeTo uint64) {
s.scan.TsRangeFrom = tsRangeFrom
s.scan.TsRangeTo = tsRangeTo
}
func (s *ThemisScanner) SetMaxVersions(maxVersions uint32) {
s.scan.MaxVersions = maxVersions
}
func (s *ThemisScanner) createGetFromScan(row []byte) *hbase.Get {
return s.scan.CreateGetFromScan(row)
}
func (s *ThemisScanner) Next() *hbase.ResultRow {
r := s.scan.Next()
if r == nil {
return nil
}
// if we encounter conflict locks, we need to clean lock for this row and read again
if isLockResult(r) {
g := s.createGetFromScan(r.Row)
r, err := s.txn.tryToCleanLockAndGetAgain(s.tbl, g, r.SortedColumns)
if err != nil {
log.Error(err)
return nil
}
// empty result indicates the current row has been erased, we should get next row
if r == nil {
return s.Next()
} else {
return r
}
}
return r
}
func (s *ThemisScanner) Closed() bool {
return s.scan.Closed()
}
func (s *ThemisScanner) Close() {
if !s.scan.Closed() {
// TODO: handle error, now just log
if err := s.scan.Close(); err != nil {
log.Warnf("scanner close error, scan: %s, error: %v", s.scan, err)
}
}
}

View file

@ -0,0 +1,64 @@
package themis
import (
"bytes"
"encoding/binary"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase"
"github.com/pingcap/go-hbase/iohelper"
)
type themisSecondaryLock struct {
*themisLock
primaryCoordinate *hbase.ColumnCoordinate
}
func newThemisSecondaryLock() *themisSecondaryLock {
return &themisSecondaryLock{
themisLock: &themisLock{
clientAddr: "null",
},
primaryCoordinate: &hbase.ColumnCoordinate{},
}
}
func (l *themisSecondaryLock) Primary() Lock {
pl := newThemisPrimaryLock()
pl.coordinate = l.primaryCoordinate
pl.ts = l.ts
pl.clientAddr = l.clientAddr
pl.addSecondary(l.coordinate, l.typ)
return pl
}
func (l *themisSecondaryLock) Secondaries() []Lock {
return nil
}
func (l *themisSecondaryLock) Role() LockRole {
return RoleSecondary
}
func (l *themisSecondaryLock) Encode() []byte {
buf := bytes.NewBuffer(nil)
binary.Write(buf, binary.BigEndian, uint8(0))
l.themisLock.write(buf)
// TODO: handle error, now just log
if err := l.primaryCoordinate.Write(buf); err != nil {
log.Warnf("write error, primary coordinate: %s, buf: %s, err: %v", l, buf, err)
}
return buf.Bytes()
}
func (l *themisSecondaryLock) parse(r iohelper.ByteMultiReader) error {
l.themisLock.parse(r)
primary := &hbase.ColumnCoordinate{}
err := primary.ParseField(r)
if err != nil {
return errors.Trace(err)
}
l.primaryCoordinate = primary
return nil
}

796
vendor/github.com/pingcap/go-themis/themis_txn.go generated vendored Normal file
View file

@ -0,0 +1,796 @@
package themis
import (
"fmt"
"sync"
"time"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/go-hbase"
"github.com/pingcap/go-themis/oracle"
)
type TxnConfig struct {
ConcurrentPrewriteAndCommit bool
WaitSecondaryCommit bool
TTLInMs uint64
MaxRowsInOneTxn int
// options below is for debugging and testing
brokenPrewriteSecondaryTest bool
brokenPrewriteSecondaryAndRollbackTest bool
brokenCommitPrimaryTest bool
brokenCommitSecondaryTest bool
}
var defaultTxnConf = TxnConfig{
ConcurrentPrewriteAndCommit: true,
WaitSecondaryCommit: false,
MaxRowsInOneTxn: 50000,
TTLInMs: 5 * 1000, // default txn TTL: 5s
brokenPrewriteSecondaryTest: false,
brokenPrewriteSecondaryAndRollbackTest: false,
brokenCommitPrimaryTest: false,
brokenCommitSecondaryTest: false,
}
type themisTxn struct {
client hbase.HBaseClient
rpc *themisRPC
lockCleaner LockManager
oracle oracle.Oracle
mutationCache *columnMutationCache
startTs uint64
commitTs uint64
primaryRow *rowMutation
primary *hbase.ColumnCoordinate
secondaryRows []*rowMutation
secondary []*hbase.ColumnCoordinate
primaryRowOffset int
singleRowTxn bool
secondaryLockBytes []byte
conf TxnConfig
hooks *txnHook
}
var _ Txn = (*themisTxn)(nil)
var (
// ErrSimulated is used when maybe rollback occurs error too.
ErrSimulated = errors.New("simulated error")
maxCleanLockRetryCount = 30
pauseTime = 300 * time.Millisecond
)
func NewTxn(c hbase.HBaseClient, oracle oracle.Oracle) (Txn, error) {
return NewTxnWithConf(c, defaultTxnConf, oracle)
}
func NewTxnWithConf(c hbase.HBaseClient, conf TxnConfig, oracle oracle.Oracle) (Txn, error) {
var err error
txn := &themisTxn{
client: c,
mutationCache: newColumnMutationCache(),
oracle: oracle,
primaryRowOffset: -1,
conf: conf,
rpc: newThemisRPC(c, oracle, conf),
hooks: newHook(),
}
txn.startTs, err = txn.oracle.GetTimestamp()
if err != nil {
return nil, errors.Trace(err)
}
txn.lockCleaner = newThemisLockManager(txn.rpc, c)
return txn, nil
}
func (txn *themisTxn) setHook(hooks *txnHook) {
txn.hooks = hooks
}
func (txn *themisTxn) Gets(tbl string, gets []*hbase.Get) ([]*hbase.ResultRow, error) {
results, err := txn.rpc.themisBatchGet([]byte(tbl), gets, txn.startTs, false)
if err != nil {
return nil, errors.Trace(err)
}
var ret []*hbase.ResultRow
hasLock := false
for _, r := range results {
// if this row is locked, try clean lock and get again
if isLockResult(r) {
hasLock = true
err = txn.constructLockAndClean([]byte(tbl), r.SortedColumns)
if err != nil {
// TODO if it's a conflict error, it means this lock
// isn't expired, maybe we can retry or return partial results.
return nil, errors.Trace(err)
}
}
// it's OK, because themisBatchGet doesn't return nil value.
ret = append(ret, r)
}
if hasLock {
// after we cleaned locks, try to get again.
ret, err = txn.rpc.themisBatchGet([]byte(tbl), gets, txn.startTs, true)
if err != nil {
return nil, errors.Trace(err)
}
}
return ret, nil
}
func (txn *themisTxn) Get(tbl string, g *hbase.Get) (*hbase.ResultRow, error) {
r, err := txn.rpc.themisGet([]byte(tbl), g, txn.startTs, false)
if err != nil {
return nil, errors.Trace(err)
}
// contain locks, try to clean and get again
if r != nil && isLockResult(r) {
r, err = txn.tryToCleanLockAndGetAgain([]byte(tbl), g, r.SortedColumns)
if err != nil {
return nil, errors.Trace(err)
}
}
return r, nil
}
func (txn *themisTxn) Put(tbl string, p *hbase.Put) {
// add mutation to buffer
for _, e := range getEntriesFromPut(p) {
txn.mutationCache.addMutation([]byte(tbl), p.Row, e.Column, e.typ, e.value, false)
}
}
func (txn *themisTxn) Delete(tbl string, p *hbase.Delete) error {
entries, err := getEntriesFromDel(p)
if err != nil {
return errors.Trace(err)
}
for _, e := range entries {
txn.mutationCache.addMutation([]byte(tbl), p.Row, e.Column, e.typ, e.value, false)
}
return nil
}
func (txn *themisTxn) Commit() error {
if txn.mutationCache.getMutationCount() == 0 {
return nil
}
if txn.mutationCache.getRowCount() > txn.conf.MaxRowsInOneTxn {
return ErrTooManyRows
}
txn.selectPrimaryAndSecondaries()
err := txn.prewritePrimary()
if err != nil {
// no need to check wrong region here, hbase client will retry when
// occurs single row NotInRegion error.
log.Error(errors.ErrorStack(err))
// it's safe to retry, because this transaction is not committed.
return ErrRetryable
}
err = txn.prewriteSecondary()
if err != nil {
if isWrongRegionErr(err) {
log.Warn("region info outdated")
// reset hbase client buffered region info
txn.client.CleanAllRegionCache()
}
return ErrRetryable
}
txn.commitTs, err = txn.oracle.GetTimestamp()
if err != nil {
log.Error(errors.ErrorStack(err))
return ErrRetryable
}
err = txn.commitPrimary()
if err != nil {
// commit primary error, rollback
log.Error("commit primary row failed", txn.startTs, err)
txn.rollbackRow(txn.primaryRow.tbl, txn.primaryRow)
txn.rollbackSecondaryRow(len(txn.secondaryRows) - 1)
return ErrRetryable
}
txn.commitSecondary()
log.Debug("themis txn commit successfully", txn.startTs, txn.commitTs)
return nil
}
func (txn *themisTxn) commitSecondary() {
if bypass, _, _ := txn.hooks.beforeCommitSecondary(txn, nil); !bypass {
return
}
if txn.conf.brokenCommitSecondaryTest {
txn.brokenCommitSecondary()
return
}
if txn.conf.ConcurrentPrewriteAndCommit {
txn.batchCommitSecondary(txn.conf.WaitSecondaryCommit)
} else {
txn.commitSecondarySync()
}
}
func (txn *themisTxn) commitSecondarySync() {
for _, r := range txn.secondaryRows {
err := txn.rpc.commitSecondaryRow(r.tbl, r.row, r.mutationList(false), txn.startTs, txn.commitTs)
if err != nil {
// fail of secondary commit will not stop the commits of next
// secondaries
log.Warning(err)
}
}
}
func (txn *themisTxn) batchCommitSecondary(wait bool) error {
//will batch commit all rows in a region
rsRowMap, err := txn.groupByRegion()
if err != nil {
return errors.Trace(err)
}
wg := sync.WaitGroup{}
for _, regionRowMap := range rsRowMap {
wg.Add(1)
_, firstRowM := getFirstEntity(regionRowMap)
go func(cli *themisRPC, tbl string, rMap map[string]*rowMutation, startTs, commitTs uint64) {
defer wg.Done()
err := cli.batchCommitSecondaryRows([]byte(tbl), rMap, startTs, commitTs)
if err != nil {
// fail of secondary commit will not stop the commits of next
// secondaries
if isWrongRegionErr(err) {
txn.client.CleanAllRegionCache()
log.Warn("region info outdated when committing secondary rows, don't panic")
}
}
}(txn.rpc, string(firstRowM.tbl), regionRowMap, txn.startTs, txn.commitTs)
}
if wait {
wg.Wait()
}
return nil
}
func (txn *themisTxn) groupByRegion() (map[string]map[string]*rowMutation, error) {
rsRowMap := make(map[string]map[string]*rowMutation)
for _, rm := range txn.secondaryRows {
region, err := txn.client.LocateRegion(rm.tbl, rm.row, true)
if err != nil {
return nil, errors.Trace(err)
}
key := getBatchGroupKey(region, string(rm.tbl))
if _, exists := rsRowMap[key]; !exists {
rsRowMap[key] = map[string]*rowMutation{}
}
rsRowMap[key][string(rm.row)] = rm
}
return rsRowMap, nil
}
func (txn *themisTxn) commitPrimary() error {
if txn.conf.brokenCommitPrimaryTest {
return txn.brokenCommitPrimary()
}
return txn.rpc.commitRow(txn.primary.Table, txn.primary.Row,
txn.primaryRow.mutationList(false),
txn.startTs, txn.commitTs, txn.primaryRowOffset)
}
func (txn *themisTxn) selectPrimaryAndSecondaries() {
txn.secondary = nil
for tblName, rowMutations := range txn.mutationCache.mutations {
for _, rowMutation := range rowMutations {
row := rowMutation.row
findPrimaryInRow := false
for i, mutation := range rowMutation.mutationList(true) {
colcord := hbase.NewColumnCoordinate([]byte(tblName), row, mutation.Family, mutation.Qual)
// set the first column as primary if primary is not set by user
if txn.primaryRowOffset == -1 &&
(txn.primary == nil || txn.primary.Equal(colcord)) {
txn.primary = colcord
txn.primaryRowOffset = i
txn.primaryRow = rowMutation
findPrimaryInRow = true
} else {
txn.secondary = append(txn.secondary, colcord)
}
}
if !findPrimaryInRow {
txn.secondaryRows = append(txn.secondaryRows, rowMutation)
}
}
}
// hook for test
if bypass, _, _ := txn.hooks.afterChoosePrimaryAndSecondary(txn, nil); !bypass {
return
}
if len(txn.secondaryRows) == 0 {
txn.singleRowTxn = true
}
// construct secondary lock
secondaryLock := txn.constructSecondaryLock(hbase.TypePut)
if secondaryLock != nil {
txn.secondaryLockBytes = secondaryLock.Encode()
} else {
txn.secondaryLockBytes = nil
}
}
func (txn *themisTxn) constructSecondaryLock(typ hbase.Type) *themisSecondaryLock {
if txn.primaryRow.getSize() <= 1 && len(txn.secondaryRows) == 0 {
return nil
}
l := newThemisSecondaryLock()
l.primaryCoordinate = txn.primary
l.ts = txn.startTs
// TODO set client addr
return l
}
func (txn *themisTxn) constructPrimaryLock() *themisPrimaryLock {
l := newThemisPrimaryLock()
l.typ = txn.primaryRow.getType(txn.primary.Column)
l.ts = txn.startTs
for _, c := range txn.secondary {
l.addSecondary(c, txn.mutationCache.getMutation(c).typ)
}
return l
}
func (txn *themisTxn) constructLockAndClean(tbl []byte, lockKvs []*hbase.Kv) error {
locks, err := getLocksFromResults([]byte(tbl), lockKvs, txn.rpc)
if err != nil {
return errors.Trace(err)
}
for _, lock := range locks {
err := txn.cleanLockWithRetry(lock)
if err != nil {
return errors.Trace(err)
}
}
return nil
}
func (txn *themisTxn) tryToCleanLockAndGetAgain(tbl []byte, g *hbase.Get, lockKvs []*hbase.Kv) (*hbase.ResultRow, error) {
// try to clean locks
err := txn.constructLockAndClean(tbl, lockKvs)
if err != nil {
return nil, errors.Trace(err)
}
// get again, ignore lock
r, err := txn.rpc.themisGet([]byte(tbl), g, txn.startTs, true)
if err != nil {
return nil, errors.Trace(err)
}
return r, nil
}
func (txn *themisTxn) commitSecondaryAndCleanLock(lock *themisSecondaryLock, commitTs uint64) error {
cc := lock.Coordinate()
mutation := &columnMutation{
Column: &cc.Column,
mutationValuePair: &mutationValuePair{
typ: lock.typ,
},
}
err := txn.rpc.commitSecondaryRow(cc.Table, cc.Row,
[]*columnMutation{mutation}, lock.Timestamp(), commitTs)
if err != nil {
return errors.Trace(err)
}
return nil
}
func (txn *themisTxn) cleanLockWithRetry(lock Lock) error {
for i := 0; i < maxCleanLockRetryCount; i++ {
if exists, err := txn.lockCleaner.IsLockExists(lock.Coordinate(), 0, lock.Timestamp()); err != nil || !exists {
return errors.Trace(err)
}
log.Warnf("lock exists txn: %v lock-txn: %v row: %q", txn.startTs, lock.Timestamp(), lock.Coordinate().Row)
// try clean lock
err := txn.tryToCleanLock(lock)
if errorEqual(err, ErrLockNotExpired) {
log.Warn("sleep a while, and retry clean lock", txn.startTs)
// TODO(dongxu) use cleverer retry sleep time interval
time.Sleep(pauseTime)
continue
} else if err != nil {
return errors.Trace(err)
}
// lock cleaned successfully
return nil
}
return ErrCleanLockFailed
}
func (txn *themisTxn) tryToCleanLock(lock Lock) error {
// if it's secondary lock, first we'll check if its primary lock has been released.
if lock.Role() == RoleSecondary {
// get primary lock
pl := lock.Primary()
// check primary lock is exists
exists, err := txn.lockCleaner.IsLockExists(pl.Coordinate(), 0, pl.Timestamp())
if err != nil {
return errors.Trace(err)
}
if !exists {
// primary row is committed, commit this row
cc := pl.Coordinate()
commitTs, err := txn.lockCleaner.GetCommitTimestamp(cc, pl.Timestamp())
if err != nil {
return errors.Trace(err)
}
if commitTs > 0 {
// if this transction has been committed
log.Info("txn has been committed, ts:", commitTs, "prewriteTs:", pl.Timestamp())
// commit secondary rows
err := txn.commitSecondaryAndCleanLock(lock.(*themisSecondaryLock), commitTs)
if err != nil {
return errors.Trace(err)
}
return nil
}
}
}
expired, err := txn.rpc.checkAndSetLockIsExpired(lock)
if err != nil {
return errors.Trace(err)
}
// only clean expired lock
if expired {
// try to clean primary lock
pl := lock.Primary()
commitTs, cleanedLock, err := txn.lockCleaner.CleanLock(pl.Coordinate(), pl.Timestamp())
if err != nil {
return errors.Trace(err)
}
if cleanedLock != nil {
pl = cleanedLock
}
log.Info("try clean secondary locks", pl.Timestamp())
// clean secondary locks
// erase lock and data if commitTs is 0; otherwise, commit it.
for k, v := range pl.(*themisPrimaryLock).secondaries {
cc := &hbase.ColumnCoordinate{}
if err = cc.ParseFromString(k); err != nil {
return errors.Trace(err)
}
if commitTs == 0 {
// commitTs == 0, means clean primary lock successfully
// expire trx havn't committed yet, we must delete lock and
// dirty data
err = txn.lockCleaner.EraseLockAndData(cc, pl.Timestamp())
if err != nil {
return errors.Trace(err)
}
} else {
// primary row is committed, so we must commit other
// secondary rows
mutation := &columnMutation{
Column: &cc.Column,
mutationValuePair: &mutationValuePair{
typ: v,
},
}
err = txn.rpc.commitSecondaryRow(cc.Table, cc.Row,
[]*columnMutation{mutation}, pl.Timestamp(), commitTs)
if err != nil {
return errors.Trace(err)
}
}
}
} else {
return ErrLockNotExpired
}
return nil
}
func (txn *themisTxn) batchPrewriteSecondaryRowsWithLockClean(tbl []byte, rowMs map[string]*rowMutation) error {
locks, err := txn.batchPrewriteSecondaryRows(tbl, rowMs)
if err != nil {
return errors.Trace(err)
}
// lock clean
if locks != nil && len(locks) > 0 {
// hook for test
if bypass, _, err := txn.hooks.onSecondaryOccursLock(txn, locks); !bypass {
return errors.Trace(err)
}
// try one more time after clean lock successfully
for _, lock := range locks {
err = txn.cleanLockWithRetry(lock)
if err != nil {
return errors.Trace(err)
}
// prewrite all secondary rows
locks, err = txn.batchPrewriteSecondaryRows(tbl, rowMs)
if err != nil {
return errors.Trace(err)
}
if len(locks) > 0 {
for _, l := range locks {
log.Errorf("can't clean lock, column:%q; conflict lock: %+v, lock ts: %d", l.Coordinate(), l, l.Timestamp())
}
return ErrRetryable
}
}
}
return nil
}
func (txn *themisTxn) prewriteRowWithLockClean(tbl []byte, mutation *rowMutation, containPrimary bool) error {
lock, err := txn.prewriteRow(tbl, mutation, containPrimary)
if err != nil {
return errors.Trace(err)
}
// lock clean
if lock != nil {
// hook for test
if bypass, _, err := txn.hooks.beforePrewriteLockClean(txn, lock); !bypass {
return errors.Trace(err)
}
err = txn.cleanLockWithRetry(lock)
if err != nil {
return errors.Trace(err)
}
// try one more time after clean lock successfully
lock, err = txn.prewriteRow(tbl, mutation, containPrimary)
if err != nil {
return errors.Trace(err)
}
if lock != nil {
log.Errorf("can't clean lock, column:%q; conflict lock: %+v, lock ts: %d", lock.Coordinate(), lock, lock.Timestamp())
return ErrRetryable
}
}
return nil
}
func (txn *themisTxn) batchPrewriteSecondaryRows(tbl []byte, rowMs map[string]*rowMutation) (map[string]Lock, error) {
return txn.rpc.batchPrewriteSecondaryRows(tbl, rowMs, txn.startTs, txn.secondaryLockBytes)
}
func (txn *themisTxn) prewriteRow(tbl []byte, mutation *rowMutation, containPrimary bool) (Lock, error) {
// hook for test
if bypass, ret, err := txn.hooks.onPrewriteRow(txn, []interface{}{mutation, containPrimary}); !bypass {
return ret.(Lock), errors.Trace(err)
}
if containPrimary {
// try to get lock
return txn.rpc.prewriteRow(tbl, mutation.row,
mutation.mutationList(true),
txn.startTs,
txn.constructPrimaryLock().Encode(),
txn.secondaryLockBytes, txn.primaryRowOffset)
}
return txn.rpc.prewriteSecondaryRow(tbl, mutation.row,
mutation.mutationList(true),
txn.startTs,
txn.secondaryLockBytes)
}
func (txn *themisTxn) prewritePrimary() error {
// hook for test
if bypass, _, err := txn.hooks.beforePrewritePrimary(txn, nil); !bypass {
return err
}
err := txn.prewriteRowWithLockClean(txn.primary.Table, txn.primaryRow, true)
if err != nil {
log.Debugf("prewrite primary %v %q failed: %v", txn.startTs, txn.primaryRow.row, err.Error())
return errors.Trace(err)
}
log.Debugf("prewrite primary %v %q successfully", txn.startTs, txn.primaryRow.row)
return nil
}
func (txn *themisTxn) prewriteSecondary() error {
// hook for test
if bypass, _, err := txn.hooks.beforePrewriteSecondary(txn, nil); !bypass {
return err
}
if txn.conf.brokenPrewriteSecondaryTest {
return txn.brokenPrewriteSecondary()
}
if txn.conf.ConcurrentPrewriteAndCommit {
return txn.batchPrewriteSecondaries()
}
return txn.prewriteSecondarySync()
}
func (txn *themisTxn) prewriteSecondarySync() error {
for i, mu := range txn.secondaryRows {
err := txn.prewriteRowWithLockClean(mu.tbl, mu, false)
if err != nil {
// rollback
txn.rollbackRow(txn.primaryRow.tbl, txn.primaryRow)
txn.rollbackSecondaryRow(i)
return errors.Trace(err)
}
}
return nil
}
// just for test
func (txn *themisTxn) brokenCommitPrimary() error {
// do nothing
log.Warn("Simulating primary commit failed")
return nil
}
// just for test
func (txn *themisTxn) brokenCommitSecondary() {
// do nothing
log.Warn("Simulating secondary commit failed")
}
func (txn *themisTxn) brokenPrewriteSecondary() error {
log.Warn("Simulating prewrite secondary failed")
for i, rm := range txn.secondaryRows {
if i == len(txn.secondary)-1 {
if !txn.conf.brokenPrewriteSecondaryAndRollbackTest {
// simulating prewrite failed, need rollback
txn.rollbackRow(txn.primaryRow.tbl, txn.primaryRow)
txn.rollbackSecondaryRow(i)
}
// maybe rollback occurs error too
return ErrSimulated
}
txn.prewriteRowWithLockClean(rm.tbl, rm, false)
}
return nil
}
func (txn *themisTxn) batchPrewriteSecondaries() error {
wg := sync.WaitGroup{}
//will batch prewrite all rows in a region
rsRowMap, err := txn.groupByRegion()
if err != nil {
return errors.Trace(err)
}
errChan := make(chan error, len(rsRowMap))
defer close(errChan)
successChan := make(chan map[string]*rowMutation, len(rsRowMap))
defer close(successChan)
for _, regionRowMap := range rsRowMap {
wg.Add(1)
_, firstRowM := getFirstEntity(regionRowMap)
go func(tbl []byte, rMap map[string]*rowMutation) {
defer wg.Done()
err := txn.batchPrewriteSecondaryRowsWithLockClean(tbl, rMap)
if err != nil {
errChan <- err
} else {
successChan <- rMap
}
}(firstRowM.tbl, regionRowMap)
}
wg.Wait()
if len(errChan) != 0 {
// occur error, clean success prewrite mutations
log.Warnf("batch prewrite secondary rows error, rolling back %d %d", len(successChan), txn.startTs)
txn.rollbackRow(txn.primaryRow.tbl, txn.primaryRow)
L:
for {
select {
case succMutMap := <-successChan:
{
for _, rowMut := range succMutMap {
txn.rollbackRow(rowMut.tbl, rowMut)
}
}
default:
break L
}
}
err := <-errChan
if err != nil {
log.Error("batch prewrite secondary rows error, txn:", txn.startTs, err)
}
return errors.Trace(err)
}
return nil
}
func getFirstEntity(rowMap map[string]*rowMutation) (string, *rowMutation) {
for row, rowM := range rowMap {
return row, rowM
}
return "", nil
}
func getBatchGroupKey(rInfo *hbase.RegionInfo, tblName string) string {
return rInfo.Server + "_" + rInfo.Name
}
func (txn *themisTxn) rollbackRow(tbl []byte, mutation *rowMutation) error {
l := fmt.Sprintf("\nrolling back %q %d {\n", mutation.row, txn.startTs)
for _, v := range mutation.getColumns() {
l += fmt.Sprintf("\t%s:%s\n", string(v.Family), string(v.Qual))
}
l += "}\n"
log.Warn(l)
for _, col := range mutation.getColumns() {
cc := &hbase.ColumnCoordinate{
Table: tbl,
Row: mutation.row,
Column: col,
}
err := txn.lockCleaner.EraseLockAndData(cc, txn.startTs)
if err != nil {
return errors.Trace(err)
}
}
return nil
}
func (txn *themisTxn) rollbackSecondaryRow(successIndex int) error {
for i := successIndex; i >= 0; i-- {
r := txn.secondaryRows[i]
err := txn.rollbackRow(r.tbl, r)
if err != nil {
return errors.Trace(err)
}
}
return nil
}
func (txn *themisTxn) GetScanner(tbl []byte, startKey, endKey []byte, batchSize int) *ThemisScanner {
scanner := newThemisScanner(tbl, txn, batchSize, txn.client)
if startKey != nil {
scanner.setStartRow(startKey)
}
if endKey != nil {
scanner.setStopRow(endKey)
}
return scanner
}
func (txn *themisTxn) Release() {
txn.primary = nil
txn.primaryRow = nil
txn.secondary = nil
txn.secondaryRows = nil
txn.startTs = 0
txn.commitTs = 0
}
func (txn *themisTxn) String() string {
return fmt.Sprintf("%d", txn.startTs)
}
func (txn *themisTxn) GetCommitTS() uint64 {
return txn.commitTs
}
func (txn *themisTxn) GetStartTS() uint64 {
return txn.startTs
}
func (txn *themisTxn) LockRow(tbl string, rowkey []byte) error {
g := hbase.NewGet(rowkey)
r, err := txn.Get(tbl, g)
if err != nil {
log.Warnf("get row error, table:%s, row:%q, error:%v", tbl, rowkey, err)
return errors.Trace(err)
}
if r == nil {
log.Warnf("has not data to lock, table:%s, row:%q", tbl, rowkey)
return nil
}
for _, v := range r.Columns {
txn.mutationCache.addMutation([]byte(tbl), rowkey, &v.Column, hbase.TypeMinimum, nil, true)
}
return nil
}

28
vendor/github.com/pingcap/go-themis/txn.go generated vendored Normal file
View file

@ -0,0 +1,28 @@
package themis
import (
"errors"
"github.com/pingcap/go-hbase"
)
var (
ErrLockNotExpired = errors.New("lock not expired")
ErrCleanLockFailed = errors.New("clean lock failed")
ErrWrongRegion = errors.New("wrong region, please retry")
ErrTooManyRows = errors.New("too many rows in one transaction")
ErrRetryable = errors.New("try again later")
)
type Txn interface {
Get(t string, get *hbase.Get) (*hbase.ResultRow, error)
Gets(t string, gets []*hbase.Get) ([]*hbase.ResultRow, error)
LockRow(t string, row []byte) error
Put(t string, put *hbase.Put)
Delete(t string, del *hbase.Delete) error
GetScanner(tbl []byte, startKey, endKey []byte, batchSize int) *ThemisScanner
Release()
Commit() error
GetStartTS() uint64
GetCommitTS() uint64
}

36
vendor/github.com/pingcap/go-themis/txn_hook.go generated vendored Normal file
View file

@ -0,0 +1,36 @@
package themis
// Hooks for debugging and testing
type fnHook func(txn *themisTxn, ctx interface{}) (bypass bool, ret interface{}, err error)
var emptyHookFn = func(txn *themisTxn, ctx interface{}) (bypass bool, ret interface{}, err error) {
return true, nil, nil
}
type txnHook struct {
afterChoosePrimaryAndSecondary fnHook
beforePrewritePrimary fnHook
beforePrewriteLockClean fnHook
beforePrewriteSecondary fnHook
beforeCommitPrimary fnHook
beforeCommitSecondary fnHook
onSecondaryOccursLock fnHook
onPrewriteRow fnHook
onTxnSuccess fnHook
onTxnFailed fnHook
}
func newHook() *txnHook {
return &txnHook{
afterChoosePrimaryAndSecondary: emptyHookFn,
beforePrewritePrimary: emptyHookFn,
beforePrewriteLockClean: emptyHookFn,
beforePrewriteSecondary: emptyHookFn,
beforeCommitPrimary: emptyHookFn,
beforeCommitSecondary: emptyHookFn,
onSecondaryOccursLock: emptyHookFn,
onPrewriteRow: emptyHookFn,
onTxnSuccess: emptyHookFn,
onTxnFailed: emptyHookFn,
}
}

22
vendor/github.com/pingcap/go-themis/util.go generated vendored Normal file
View file

@ -0,0 +1,22 @@
package themis
import "github.com/juju/errors"
func errorEqual(err1, err2 error) bool {
if err1 == err2 {
return true
}
e1 := errors.Cause(err1)
e2 := errors.Cause(err2)
if e1 == e2 {
return true
}
if e1 == nil || e2 == nil {
return e1 == e2
}
return e1.Error() == e2.Error()
}

65
vendor/github.com/pingcap/tidb/CONTRIBUTING.md generated vendored Normal file
View file

@ -0,0 +1,65 @@
# How to contribute
This document outlines some of the conventions on development workflow, commit message formatting, contact points and other
resources to make it easier to get your contribution accepted.
## Getting started
- Fork the repository on GitHub.
- Read the README.md for build instructions.
- Play with the project, submit bugs, submit patches!
## Contribution flow
This is a rough outline of what a contributor's workflow looks like:
- Create a topic branch from where you want to base your work. This is usually master.
- Make commits of logical units and add test case if the change fixes a bug or adds new functionality.
- Run tests and make sure all the tests are passed.
- Make sure your commit messages are in the proper format (see below).
- Push your changes to a topic branch in your fork of the repository.
- Submit a pull request to pingcap/tidb.
- Your PR must receive LGTMs from two maintainers found in the [MAINTAINERS](./docs/MAINTAINERS.md) file.
Thanks for your contributions!
### Code style
The coding style suggested by the Golang community is used in TiDB. See the [style doc](https://github.com/golang/go/wiki/CodeReviewComments) for details.
Please follow this style to make TiDB easy to review, maintain and develop.
### Format of the Commit Message
We follow a rough convention for commit messages that is designed to answer two
questions: what changed and why. The subject line should feature the what and
the body of the commit should describe the why.
```
store/localstore: add comment for variable declaration.
Improve documentation.
```
The format can be described more formally as follows:
```
<subsystem>: <what changed>
<BLANK LINE>
<why this change was made>
<BLANK LINE>
<footer>(optional)
```
The first line is the subject and should be no longer than 70 characters, the
second line is always blank, and other lines should be wrapped at 80 characters.
This allows the message to be easier to read on GitHub as well as in various
git tools.
If the change affects more than one subsystem, you can use comma to separate them like `util/codec,util/types:`.
If the change affects many subsystems, you can use ```*``` instead, like ```*:```.
For the why part, if no specific reason for the change,
you can use one of some generic reasons like "Improve documentation.",
"Improve performance.", "Improve robustness.", "Improve test coverage."

15
vendor/github.com/pingcap/tidb/Dockerfile generated vendored Normal file
View file

@ -0,0 +1,15 @@
FROM golang
VOLUME /opt
RUN apt-get update && apt-get install -y wget git make ; \
cd /opt ; \
export PATH=$GOROOT/bin:$GOPATH/bin:$PATH ; \
go get -d github.com/pingcap/tidb ; \
cd $GOPATH/src/github.com/pingcap/tidb ; \
make ; make server ; cp tidb-server/tidb-server /usr/bin/
EXPOSE 4000
CMD ["/usr/bin/tidb-server"]

138
vendor/github.com/pingcap/tidb/Makefile generated vendored Normal file
View file

@ -0,0 +1,138 @@
### Makefile for tidb
# Ensure GOPATH is set before running build process.
ifeq "$(GOPATH)" ""
$(error Please set the environment variable GOPATH before running `make`)
endif
path_to_add := $(addsuffix /bin,$(subst :,/bin:,$(GOPATH)))
export PATH := $(path_to_add):$(PATH)
# Check the version of make and set env varirables/commands accordingly.
version_list := $(subst ., ,$(MAKE_VERSION))
major_version := $(firstword $(version_list))
old_versions := 0 1 2 3
ifeq "$(major_version)" "$(filter $(major_version),$(old_versions))"
# Old version of `make` installed. It fails to search golex/goyacc
# by using the modified `PATH`, so we specify these commands with full path.
GODEP = $$(which godep)
GOLEX = $$(which golex)
GOYACC = $$(which goyacc)
GOLINT = $$(which golint)
else
# After version 4, `make` could follow modified `PATH` to find
# golex/goyacc correctly.
GODEP := godep
GOLEX := golex
GOYACC := goyacc
GOLINT := golint
endif
GO := $(GODEP) go
ARCH := "`uname -s`"
LINUX := "Linux"
MAC := "Darwin"
LDFLAGS += -X "github.com/pingcap/tidb/util/printer.TiDBBuildTS=$(shell date -u '+%Y-%m-%d %I:%M:%S')"
LDFLAGS += -X "github.com/pingcap/tidb/util/printer.TiDBGitHash=$(shell git rev-parse HEAD)"
TARGET = ""
.PHONY: godep deps all build install update parser clean todo test gotest interpreter server
all: godep build test check
godep:
go get github.com/tools/godep
go get github.com/pingcap/go-hbase
go get github.com/pingcap/go-themis
go get github.com/pingcap/tso/client
build:
$(GO) build
install:
$(GO) install ./...
update:
go get -u github.com/pingcap/go-hbase
go get -u github.com/pingcap/go-themis
go get -u github.com/pingcap/tso/client
TEMP_FILE = temp_parser_file
parser:
go get github.com/qiuyesuifeng/goyacc
go get github.com/qiuyesuifeng/golex
$(GOYACC) -o /dev/null -xegen $(TEMP_FILE) parser/parser.y
$(GOYACC) -o parser/parser.go -xe $(TEMP_FILE) parser/parser.y 2>&1 | egrep "(shift|reduce)/reduce" | awk '{print} END {if (NR > 0) {print "Find conflict in parser.y. Please check y.output for more information."; system("rm -f $(TEMP_FILE)"); exit 1;}}'
rm -f $(TEMP_FILE)
rm -f y.output
@if [ $(ARCH) = $(LINUX) ]; \
then \
sed -i -e 's|//line.*||' -e 's/yyEofCode/yyEOFCode/' parser/parser.go; \
elif [ $(ARCH) = $(MAC) ]; \
then \
/usr/bin/sed -i "" 's|//line.*||' parser/parser.go; \
/usr/bin/sed -i "" 's/yyEofCode/yyEOFCode/' parser/parser.go; \
fi
$(GOLEX) -o parser/scanner.go parser/scanner.l
@awk 'BEGIN{print "// Code generated by goyacc"} {print $0}' parser/parser.go > tmp_parser.go && mv tmp_parser.go parser/parser.go;
@awk 'BEGIN{print "// Code generated by goyacc"} {print $0}' parser/scanner.go > tmp_scanner.go && mv tmp_scanner.go parser/scanner.go;
check:
bash gitcookie.sh
go get github.com/golang/lint/golint
@echo "vet"
@ go tool vet . 2>&1 | grep -vE 'Godeps|parser/scanner.*unreachable code' | awk '{print} END{if(NR>0) {exit 1}}'
@echo "vet --shadow"
@ go tool vet --shadow . 2>&1 | grep -vE 'Godeps' | awk '{print} END{if(NR>0) {exit 1}}'
@echo "golint"
@ $(GOLINT) ./... 2>&1 | grep -vE 'LastInsertId|NewLexer|\.pb\.go' | awk '{print} END{if(NR>0) {exit 1}}'
@echo "gofmt (simplify)"
@ gofmt -s -l . 2>&1 | grep -vE 'Godeps|parser/parser.go|parser/scanner.go' | awk '{print} END{if(NR>0) {exit 1}}'
deps:
go list -f '{{range .Deps}}{{printf "%s\n" .}}{{end}}{{range .TestImports}}{{printf "%s\n" .}}{{end}}' ./... | \
sort | uniq | grep -E '[^/]+\.[^/]+/' |grep -v "pingcap/tidb" | \
awk 'BEGIN{ print "#!/bin/bash" }{ printf("go get -u %s\n", $$1) }' > deps.sh
chmod +x deps.sh
bash deps.sh
clean:
$(GO) clean -i ./...
rm -rf *.out
rm -f deps.sh
todo:
@grep -n ^[[:space:]]*_[[:space:]]*=[[:space:]][[:alpha:]][[:alnum:]]* */*.go parser/scanner.l parser/parser.y || true
@grep -n TODO */*.go parser/scanner.l parser/parser.y || true
@grep -n BUG */*.go parser/scanner.l parser/parser.y || true
@grep -n println */*.go parser/scanner.l parser/parser.y || true
test: gotest
gotest:
$(GO) test -cover ./...
race:
$(GO) test --race -cover ./...
ddl_test:
$(GO) test ./ddl/... -skip_ddl=false
ddl_race_test:
$(GO) test --race ./ddl/... -skip_ddl=false
interpreter:
@cd interpreter && $(GO) build -ldflags '$(LDFLAGS)'
server:
ifeq ($(TARGET), "")
@cd tidb-server && $(GO) build -ldflags '$(LDFLAGS)'
else
@cd tidb-server && $(GO) build -ldflags '$(LDFLAGS)' -o '$(TARGET)'
endif

62
vendor/github.com/pingcap/tidb/README.md generated vendored Normal file
View file

@ -0,0 +1,62 @@
![logo](./docs/logo_with_text.png)
[![Build Status](https://travis-ci.org/pingcap/tidb.svg?branch=master)](https://travis-ci.org/pingcap/tidb)
## What is TiDB?
TiDB is a distributed SQL database.
Inspired by the design of Google [F1](http://research.google.com/pubs/pub41344.html), TiDB supports the best features of both traditional RDBMS and NoSQL.
- __Horizontal scalability__
Grow TiDB as your business grows. You can increase the capacity simply by adding more machines.
- __Asynchronous schema changes__
Evolve TiDB schemas as your requirement evolves. You can add new columns and indices without stopping or affecting the on-going operations.
- __Consistent distributed transactions__
Think TiDB as a single-machine RDBMS. You can start a transaction that crosses multiple machines without worrying about consistency. TiDB makes your application code simple and robust.
- __Compatible with MySQL protocol__
Use TiDB as MySQL. You can replace MySQL with TiDB to power your application without changing a single line of code in most cases.
- __Written in Go__
Enjoy TiDB as much as we love Go. We believe Go code is both easy and enjoyable to work with. Go makes us improve TiDB fast and makes it easy to dive into the codebase.
- __NewSQL over HBase__
Turn HBase into NewSQL database
- __Multiple storage engine support__
Power TiDB with your most favorite engines. TiDB supports many popular storage engines in single-machine mode. You can choose from GolevelDB, LevelDB, RocksDB, LMDB, BoltDB and even more to come.
## Status
TiDB is at its early age and under heavy development, all of the features mentioned above are fully implemented.
__Please do not use it in production.__
## Roadmap
Read the [Roadmap](./docs/ROADMAP.md).
## Quick start
Read the [Quick Start](./docs/QUICKSTART.md)
## Architecture
![architecture](./docs/architecture.png)
## Contributing
Contributions are welcomed and greatly appreciated. See [CONTRIBUTING.md](CONTRIBUTING.md)
for details on submitting patches and the contribution workflow.
## Follow us
Twitter: [@PingCAP](https://twitter.com/PingCAP)
## License
TiDB is under the Apache 2.0 license. See the [LICENSE](./LICENSES/LICENSE) file for details.
## Acknowledgments
- Thanks [cznic](https://github.com/cznic) for providing some great open source tools.
- Thanks [Xiaomi](https://github.com/XiaoMi/themis) for providing the great open source project.
- Thanks [HBase](https://hbase.apache.org), [GolevelDB](https://github.com/syndtr/goleveldb), [LMDB](https://github.com/LMDB/lmdb), [BoltDB](https://github.com/boltdb/bolt) and [RocksDB](https://github.com/facebook/rocksdb) for their powerful storage engines.

189
vendor/github.com/pingcap/tidb/ast/ast.go generated vendored Normal file
View file

@ -0,0 +1,189 @@
// 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 ast is the abstract syntax tree parsed from a SQL statement by parser.
// It can be analysed and transformed by optimizer.
package ast
import (
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/util/types"
)
// Node is the basic element of the AST.
// Interfaces embed Node should have 'Node' name suffix.
type Node interface {
// Accept accepts Visitor to visit itself.
// The returned node should replace original node.
// ok returns false to stop visiting.
//
// Implementation of this method should first call visitor.Enter,
// assign the returned node to its method receiver, if skipChildren returns true,
// children should be skipped. Otherwise, call its children in particular order that
// later elements depends on former elements. Finally, return visitor.Leave.
Accept(v Visitor) (node Node, ok bool)
// Text returns the original text of the element.
Text() string
// SetText sets original text to the Node.
SetText(text string)
}
// Flags indicates whether an expression contains certain types of expression.
const (
FlagConstant uint64 = 0
FlagHasParamMarker uint64 = 1 << iota
FlagHasFunc
FlagHasReference
FlagHasAggregateFunc
FlagHasSubquery
FlagHasVariable
FlagHasDefault
)
// ExprNode is a node that can be evaluated.
// Name of implementations should have 'Expr' suffix.
type ExprNode interface {
// Node is embeded in ExprNode.
Node
// SetType sets evaluation type to the expression.
SetType(tp *types.FieldType)
// GetType gets the evaluation type of the expression.
GetType() *types.FieldType
// SetValue sets value to the expression.
SetValue(val interface{})
// GetValue gets value of the expression.
GetValue() interface{}
// SetDatum sets datum to the expression.
SetDatum(datum types.Datum)
// GetDatum gets datum of the expression.
GetDatum() *types.Datum
// SetFlag sets flag to the expression.
// Flag indicates whether the expression contains
// parameter marker, reference, aggregate function...
SetFlag(flag uint64)
// GetFlag returns the flag of the expression.
GetFlag() uint64
}
// FuncNode represents function call expression node.
type FuncNode interface {
ExprNode
functionExpression()
}
// StmtNode represents statement node.
// Name of implementations should have 'Stmt' suffix.
type StmtNode interface {
Node
statement()
}
// DDLNode represents DDL statement node.
type DDLNode interface {
StmtNode
ddlStatement()
}
// DMLNode represents DML statement node.
type DMLNode interface {
StmtNode
dmlStatement()
}
// ResultField represents a result field which can be a column from a table,
// or an expression in select field. It is a generated property during
// binding process. ResultField is the key element to evaluate a ColumnNameExpr.
// After resolving process, every ColumnNameExpr will be resolved to a ResultField.
// During execution, every row retrieved from table will set the row value to
// ResultFields of that table, so ColumnNameExpr resolved to that ResultField can be
// easily evaluated.
type ResultField struct {
Column *model.ColumnInfo
ColumnAsName model.CIStr
Table *model.TableInfo
TableAsName model.CIStr
DBName model.CIStr
// The expression for the result field. If it is generated from a select field, it would
// be the expression of that select field, otherwise the type would be ValueExpr and value
// will be set for every retrieved row.
Expr ExprNode
TableName *TableName
}
// Row represents a single row from Recordset.
type Row struct {
Data []types.Datum
}
// RecordSet is an abstract result set interface to help get data from Plan.
type RecordSet interface {
// Fields gets result fields.
Fields() (fields []*ResultField, err error)
// Next returns the next row, nil row means there is no more to return.
Next() (row *Row, err error)
// Close closes the underlying iterator, call Next after Close will
// restart the iteration.
Close() error
}
// ResultSetNode interface has ResultFields property which is computed and set by
// optimizer.InfoBinder during binding process. Implementations include SelectStmt,
// SubqueryExpr, TableSource, TableName and Join.
type ResultSetNode interface {
Node
// GetResultFields gets result fields of the result set node.
GetResultFields() []*ResultField
// SetResultFields sets result fields of the result set node.
SetResultFields(fields []*ResultField)
}
// Statement is an interface for SQL execution.
// NOTE: all Statement implementations must be safe for
// concurrent using by multiple goroutines.
// If the Exec method requires any Execution domain local data,
// they must be held out of the implementing instance.
type Statement interface {
// Explain gets the execution plans.
//Explain(ctx context.Context, w format.Formatter)
// IsDDL shows whether the statement is an DDL operation.
IsDDL() bool
// OriginText gets the origin SQL text.
OriginText() string
// SetText sets the executive SQL text.
SetText(text string)
// Exec executes SQL and gets a Recordset.
Exec(ctx context.Context) (RecordSet, error)
}
// Visitor visits a Node.
type Visitor interface {
// Enter is called before children nodes are visited.
// The returned node must be the same type as the input node n.
// skipChildren returns true means children nodes should be skipped,
// this is useful when work is done in Enter and there is no need to visit children.
Enter(n Node) (node Node, skipChildren bool)
// Leave is called after children nodes have been visited.
// The returned node's type can be different from the input node if it is a ExprNode,
// Non-expression node must be the same type as the input node n.
// ok returns false to stop visiting.
Leave(n Node) (node Node, ok bool)
}

119
vendor/github.com/pingcap/tidb/ast/base.go generated vendored Normal file
View file

@ -0,0 +1,119 @@
// 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 ast
import "github.com/pingcap/tidb/util/types"
// node is the struct implements node interface except for Accept method.
// Node implementations should embed it in.
type node struct {
text string
}
// SetText implements Node interface.
func (n *node) SetText(text string) {
n.text = text
}
// Text implements Node interface.
func (n *node) Text() string {
return n.text
}
// stmtNode implements StmtNode interface.
// Statement implementations should embed it in.
type stmtNode struct {
node
}
// statement implements StmtNode interface.
func (sn *stmtNode) statement() {}
// ddlNode implements DDLNode interface.
// DDL implementations should embed it in.
type ddlNode struct {
stmtNode
}
// ddlStatement implements DDLNode interface.
func (dn *ddlNode) ddlStatement() {}
// dmlNode is the struct implements DMLNode interface.
// DML implementations should embed it in.
type dmlNode struct {
stmtNode
}
// dmlStatement implements DMLNode interface.
func (dn *dmlNode) dmlStatement() {}
// expressionNode is the struct implements Expression interface.
// Expression implementations should embed it in.
type exprNode struct {
node
types.Datum
Type *types.FieldType
flag uint64
}
// SetDatum implements Expression interface.
func (en *exprNode) SetDatum(datum types.Datum) {
en.Datum = datum
}
// GetDatum implements Expression interface.
func (en *exprNode) GetDatum() *types.Datum {
return &en.Datum
}
// SetType implements Expression interface.
func (en *exprNode) SetType(tp *types.FieldType) {
en.Type = tp
}
// GetType implements Expression interface.
func (en *exprNode) GetType() *types.FieldType {
return en.Type
}
// SetFlag implements Expression interface.
func (en *exprNode) SetFlag(flag uint64) {
en.flag = flag
}
// GetFlag implements Expression interface.
func (en *exprNode) GetFlag() uint64 {
return en.flag
}
type funcNode struct {
exprNode
}
// FunctionExpression implements FounctionNode interface.
func (fn *funcNode) functionExpression() {}
type resultSetNode struct {
resultFields []*ResultField
}
// GetResultFields implements ResultSetNode interface.
func (rs *resultSetNode) GetResultFields() []*ResultField {
return rs.resultFields
}
// GetResultFields implements ResultSetNode interface.
func (rs *resultSetNode) SetResultFields(rfs []*ResultField) {
rs.resultFields = rfs
}

170
vendor/github.com/pingcap/tidb/ast/cloner.go generated vendored Normal file
View file

@ -0,0 +1,170 @@
// 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 ast
import "fmt"
// Cloner is an ast visitor that clones a node.
type Cloner struct {
}
// Enter implements Visitor Enter interface.
func (c *Cloner) Enter(node Node) (Node, bool) {
return copyStruct(node), false
}
// Leave implements Visitor Leave interface.
func (c *Cloner) Leave(in Node) (out Node, ok bool) {
return in, true
}
// copyStruct copies a node's struct value, if the struct has slice member,
// make a new slice and copy old slice value to new slice.
func copyStruct(in Node) (out Node) {
switch v := in.(type) {
case *ValueExpr:
nv := *v
out = &nv
case *BetweenExpr:
nv := *v
out = &nv
case *BinaryOperationExpr:
nv := *v
out = &nv
case *WhenClause:
nv := *v
out = &nv
case *CaseExpr:
nv := *v
nv.WhenClauses = make([]*WhenClause, len(v.WhenClauses))
copy(nv.WhenClauses, v.WhenClauses)
out = &nv
case *SubqueryExpr:
nv := *v
out = &nv
case *CompareSubqueryExpr:
nv := *v
out = &nv
case *ColumnName:
nv := *v
out = &nv
case *ColumnNameExpr:
nv := *v
out = &nv
case *DefaultExpr:
nv := *v
out = &nv
case *ExistsSubqueryExpr:
nv := *v
out = &nv
case *PatternInExpr:
nv := *v
nv.List = make([]ExprNode, len(v.List))
copy(nv.List, v.List)
out = &nv
case *IsNullExpr:
nv := *v
out = &nv
case *IsTruthExpr:
nv := *v
out = &nv
case *PatternLikeExpr:
nv := *v
out = &nv
case *ParamMarkerExpr:
nv := *v
out = &nv
case *ParenthesesExpr:
nv := *v
out = &nv
case *PositionExpr:
nv := *v
out = &nv
case *PatternRegexpExpr:
nv := *v
out = &nv
case *RowExpr:
nv := *v
nv.Values = make([]ExprNode, len(v.Values))
copy(nv.Values, v.Values)
out = &nv
case *UnaryOperationExpr:
nv := *v
out = &nv
case *ValuesExpr:
nv := *v
out = &nv
case *VariableExpr:
nv := *v
out = &nv
case *Join:
nv := *v
out = &nv
case *TableName:
nv := *v
out = &nv
case *TableSource:
nv := *v
out = &nv
case *OnCondition:
nv := *v
out = &nv
case *WildCardField:
nv := *v
out = &nv
case *SelectField:
nv := *v
out = &nv
case *FieldList:
nv := *v
nv.Fields = make([]*SelectField, len(v.Fields))
copy(nv.Fields, v.Fields)
out = &nv
case *TableRefsClause:
nv := *v
out = &nv
case *ByItem:
nv := *v
out = &nv
case *GroupByClause:
nv := *v
nv.Items = make([]*ByItem, len(v.Items))
copy(nv.Items, v.Items)
out = &nv
case *HavingClause:
nv := *v
out = &nv
case *OrderByClause:
nv := *v
nv.Items = make([]*ByItem, len(v.Items))
copy(nv.Items, v.Items)
out = &nv
case *SelectStmt:
nv := *v
out = &nv
case *UnionSelectList:
nv := *v
nv.Selects = make([]*SelectStmt, len(v.Selects))
copy(nv.Selects, v.Selects)
out = &nv
case *UnionStmt:
nv := *v
out = &nv
default:
// We currently only handle expression and select statement.
// Will add more when we need to.
panic("unknown ast Node type " + fmt.Sprintf("%T", v))
}
return
}

641
vendor/github.com/pingcap/tidb/ast/ddl.go generated vendored Normal file
View file

@ -0,0 +1,641 @@
// 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 ast
import (
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/util/types"
)
var (
_ DDLNode = &AlterTableStmt{}
_ DDLNode = &CreateDatabaseStmt{}
_ DDLNode = &CreateIndexStmt{}
_ DDLNode = &CreateTableStmt{}
_ DDLNode = &DropDatabaseStmt{}
_ DDLNode = &DropIndexStmt{}
_ DDLNode = &DropTableStmt{}
_ DDLNode = &TruncateTableStmt{}
_ Node = &AlterTableSpec{}
_ Node = &ColumnDef{}
_ Node = &ColumnOption{}
_ Node = &ColumnPosition{}
_ Node = &Constraint{}
_ Node = &IndexColName{}
_ Node = &ReferenceDef{}
)
// CharsetOpt is used for parsing charset option from SQL.
type CharsetOpt struct {
Chs string
Col string
}
// DatabaseOptionType is the type for database options.
type DatabaseOptionType int
// Database option types.
const (
DatabaseOptionNone DatabaseOptionType = iota
DatabaseOptionCharset
DatabaseOptionCollate
)
// DatabaseOption represents database option.
type DatabaseOption struct {
Tp DatabaseOptionType
Value string
}
// CreateDatabaseStmt is a statement to create a database.
// See: https://dev.mysql.com/doc/refman/5.7/en/create-database.html
type CreateDatabaseStmt struct {
ddlNode
IfNotExists bool
Name string
Options []*DatabaseOption
}
// Accept implements Node Accept interface.
func (n *CreateDatabaseStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*CreateDatabaseStmt)
return v.Leave(n)
}
// DropDatabaseStmt is a statement to drop a database and all tables in the database.
// See: https://dev.mysql.com/doc/refman/5.7/en/drop-database.html
type DropDatabaseStmt struct {
ddlNode
IfExists bool
Name string
}
// Accept implements Node Accept interface.
func (n *DropDatabaseStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DropDatabaseStmt)
return v.Leave(n)
}
// IndexColName is used for parsing index column name from SQL.
type IndexColName struct {
node
Column *ColumnName
Length int
}
// Accept implements Node Accept interface.
func (n *IndexColName) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*IndexColName)
node, ok := n.Column.Accept(v)
if !ok {
return n, false
}
n.Column = node.(*ColumnName)
return v.Leave(n)
}
// ReferenceDef is used for parsing foreign key reference option from SQL.
// See: http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html
type ReferenceDef struct {
node
Table *TableName
IndexColNames []*IndexColName
}
// Accept implements Node Accept interface.
func (n *ReferenceDef) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ReferenceDef)
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableName)
for i, val := range n.IndexColNames {
node, ok = val.Accept(v)
if !ok {
return n, false
}
n.IndexColNames[i] = node.(*IndexColName)
}
return v.Leave(n)
}
// ColumnOptionType is the type for ColumnOption.
type ColumnOptionType int
// ColumnOption types.
const (
ColumnOptionNoOption ColumnOptionType = iota
ColumnOptionPrimaryKey
ColumnOptionNotNull
ColumnOptionAutoIncrement
ColumnOptionDefaultValue
ColumnOptionUniq
ColumnOptionIndex
ColumnOptionUniqIndex
ColumnOptionKey
ColumnOptionUniqKey
ColumnOptionNull
ColumnOptionOnUpdate // For Timestamp and Datetime only.
ColumnOptionFulltext
ColumnOptionComment
)
// ColumnOption is used for parsing column constraint info from SQL.
type ColumnOption struct {
node
Tp ColumnOptionType
// The value For Default or On Update.
Expr ExprNode
}
// Accept implements Node Accept interface.
func (n *ColumnOption) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ColumnOption)
if n.Expr != nil {
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
}
return v.Leave(n)
}
// IndexOption is the index options.
// KEY_BLOCK_SIZE [=] value
// | index_type
// | WITH PARSER parser_name
// | COMMENT 'string'
// See: http://dev.mysql.com/doc/refman/5.7/en/create-table.html
type IndexOption struct {
node
KeyBlockSize uint64
Tp model.IndexType
Comment string
}
// Accept implements Node Accept interface.
func (n *IndexOption) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*IndexOption)
return v.Leave(n)
}
// ConstraintType is the type for Constraint.
type ConstraintType int
// ConstraintTypes
const (
ConstraintNoConstraint ConstraintType = iota
ConstraintPrimaryKey
ConstraintKey
ConstraintIndex
ConstraintUniq
ConstraintUniqKey
ConstraintUniqIndex
ConstraintForeignKey
ConstraintFulltext
)
// Constraint is constraint for table definition.
type Constraint struct {
node
Tp ConstraintType
Name string
// Used for PRIMARY KEY, UNIQUE, ......
Keys []*IndexColName
// Used for foreign key.
Refer *ReferenceDef
// Index Options
Option *IndexOption
}
// Accept implements Node Accept interface.
func (n *Constraint) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*Constraint)
for i, val := range n.Keys {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Keys[i] = node.(*IndexColName)
}
if n.Refer != nil {
node, ok := n.Refer.Accept(v)
if !ok {
return n, false
}
n.Refer = node.(*ReferenceDef)
}
if n.Option != nil {
node, ok := n.Option.Accept(v)
if !ok {
return n, false
}
n.Option = node.(*IndexOption)
}
return v.Leave(n)
}
// ColumnDef is used for parsing column definition from SQL.
type ColumnDef struct {
node
Name *ColumnName
Tp *types.FieldType
Options []*ColumnOption
}
// Accept implements Node Accept interface.
func (n *ColumnDef) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ColumnDef)
node, ok := n.Name.Accept(v)
if !ok {
return n, false
}
n.Name = node.(*ColumnName)
for i, val := range n.Options {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Options[i] = node.(*ColumnOption)
}
return v.Leave(n)
}
// CreateTableStmt is a statement to create a table.
// See: https://dev.mysql.com/doc/refman/5.7/en/create-table.html
type CreateTableStmt struct {
ddlNode
IfNotExists bool
Table *TableName
Cols []*ColumnDef
Constraints []*Constraint
Options []*TableOption
}
// Accept implements Node Accept interface.
func (n *CreateTableStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*CreateTableStmt)
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableName)
for i, val := range n.Cols {
node, ok = val.Accept(v)
if !ok {
return n, false
}
n.Cols[i] = node.(*ColumnDef)
}
for i, val := range n.Constraints {
node, ok = val.Accept(v)
if !ok {
return n, false
}
n.Constraints[i] = node.(*Constraint)
}
return v.Leave(n)
}
// DropTableStmt is a statement to drop one or more tables.
// See: https://dev.mysql.com/doc/refman/5.7/en/drop-table.html
type DropTableStmt struct {
ddlNode
IfExists bool
Tables []*TableName
}
// Accept implements Node Accept interface.
func (n *DropTableStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DropTableStmt)
for i, val := range n.Tables {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Tables[i] = node.(*TableName)
}
return v.Leave(n)
}
// CreateIndexStmt is a statement to create an index.
// See: https://dev.mysql.com/doc/refman/5.7/en/create-index.html
type CreateIndexStmt struct {
ddlNode
IndexName string
Table *TableName
Unique bool
IndexColNames []*IndexColName
}
// Accept implements Node Accept interface.
func (n *CreateIndexStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*CreateIndexStmt)
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableName)
for i, val := range n.IndexColNames {
node, ok = val.Accept(v)
if !ok {
return n, false
}
n.IndexColNames[i] = node.(*IndexColName)
}
return v.Leave(n)
}
// DropIndexStmt is a statement to drop the index.
// See: https://dev.mysql.com/doc/refman/5.7/en/drop-index.html
type DropIndexStmt struct {
ddlNode
IfExists bool
IndexName string
Table *TableName
}
// Accept implements Node Accept interface.
func (n *DropIndexStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DropIndexStmt)
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableName)
return v.Leave(n)
}
// TableOptionType is the type for TableOption
type TableOptionType int
// TableOption types.
const (
TableOptionNone TableOptionType = iota
TableOptionEngine
TableOptionCharset
TableOptionCollate
TableOptionAutoIncrement
TableOptionComment
TableOptionAvgRowLength
TableOptionCheckSum
TableOptionCompression
TableOptionConnection
TableOptionPassword
TableOptionKeyBlockSize
TableOptionMaxRows
TableOptionMinRows
TableOptionDelayKeyWrite
TableOptionRowFormat
)
// RowFormat types
const (
RowFormatDefault uint64 = iota + 1
RowFormatDynamic
RowFormatFixed
RowFormatCompressed
RowFormatRedundant
RowFormatCompact
)
// TableOption is used for parsing table option from SQL.
type TableOption struct {
Tp TableOptionType
StrValue string
UintValue uint64
}
// ColumnPositionType is the type for ColumnPosition.
type ColumnPositionType int
// ColumnPosition Types
const (
ColumnPositionNone ColumnPositionType = iota
ColumnPositionFirst
ColumnPositionAfter
)
// ColumnPosition represent the position of the newly added column
type ColumnPosition struct {
node
// ColumnPositionNone | ColumnPositionFirst | ColumnPositionAfter
Tp ColumnPositionType
// RelativeColumn is the column the newly added column after if type is ColumnPositionAfter
RelativeColumn *ColumnName
}
// Accept implements Node Accept interface.
func (n *ColumnPosition) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ColumnPosition)
if n.RelativeColumn != nil {
node, ok := n.RelativeColumn.Accept(v)
if !ok {
return n, false
}
n.RelativeColumn = node.(*ColumnName)
}
return v.Leave(n)
}
// AlterTableType is the type for AlterTableSpec.
type AlterTableType int
// AlterTable types.
const (
AlterTableOption AlterTableType = iota + 1
AlterTableAddColumn
AlterTableAddConstraint
AlterTableDropColumn
AlterTableDropPrimaryKey
AlterTableDropIndex
AlterTableDropForeignKey
// TODO: Add more actions
)
// AlterTableSpec represents alter table specification.
type AlterTableSpec struct {
node
Tp AlterTableType
Name string
Constraint *Constraint
Options []*TableOption
Column *ColumnDef
DropColumn *ColumnName
Position *ColumnPosition
}
// Accept implements Node Accept interface.
func (n *AlterTableSpec) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*AlterTableSpec)
if n.Constraint != nil {
node, ok := n.Constraint.Accept(v)
if !ok {
return n, false
}
n.Constraint = node.(*Constraint)
}
if n.Column != nil {
node, ok := n.Column.Accept(v)
if !ok {
return n, false
}
n.Column = node.(*ColumnDef)
}
if n.DropColumn != nil {
node, ok := n.DropColumn.Accept(v)
if !ok {
return n, false
}
n.DropColumn = node.(*ColumnName)
}
if n.Position != nil {
node, ok := n.Position.Accept(v)
if !ok {
return n, false
}
n.Position = node.(*ColumnPosition)
}
return v.Leave(n)
}
// AlterTableStmt is a statement to change the structure of a table.
// See: https://dev.mysql.com/doc/refman/5.7/en/alter-table.html
type AlterTableStmt struct {
ddlNode
Table *TableName
Specs []*AlterTableSpec
}
// Accept implements Node Accept interface.
func (n *AlterTableStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*AlterTableStmt)
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableName)
for i, val := range n.Specs {
node, ok = val.Accept(v)
if !ok {
return n, false
}
n.Specs[i] = node.(*AlterTableSpec)
}
return v.Leave(n)
}
// TruncateTableStmt is a statement to empty a table completely.
// See: https://dev.mysql.com/doc/refman/5.7/en/truncate-table.html
type TruncateTableStmt struct {
ddlNode
Table *TableName
}
// Accept implements Node Accept interface.
func (n *TruncateTableStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*TruncateTableStmt)
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableName)
return v.Leave(n)
}

891
vendor/github.com/pingcap/tidb/ast/dml.go generated vendored Normal file
View file

@ -0,0 +1,891 @@
// 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 ast
import (
"github.com/pingcap/tidb/model"
)
var (
_ DMLNode = &DeleteStmt{}
_ DMLNode = &InsertStmt{}
_ DMLNode = &UnionStmt{}
_ DMLNode = &UpdateStmt{}
_ DMLNode = &SelectStmt{}
_ DMLNode = &ShowStmt{}
_ Node = &Assignment{}
_ Node = &ByItem{}
_ Node = &FieldList{}
_ Node = &GroupByClause{}
_ Node = &HavingClause{}
_ Node = &Join{}
_ Node = &Limit{}
_ Node = &OnCondition{}
_ Node = &OrderByClause{}
_ Node = &SelectField{}
_ Node = &TableName{}
_ Node = &TableRefsClause{}
_ Node = &TableSource{}
_ Node = &UnionSelectList{}
_ Node = &WildCardField{}
)
// JoinType is join type, including cross/left/right/full.
type JoinType int
const (
// CrossJoin is cross join type.
CrossJoin JoinType = iota + 1
// LeftJoin is left Join type.
LeftJoin
// RightJoin is right Join type.
RightJoin
)
// Join represents table join.
type Join struct {
node
resultSetNode
// Left table can be TableSource or JoinNode.
Left ResultSetNode
// Right table can be TableSource or JoinNode or nil.
Right ResultSetNode
// Tp represents join type.
Tp JoinType
// On represents join on condition.
On *OnCondition
}
// Accept implements Node Accept interface.
func (n *Join) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*Join)
node, ok := n.Left.Accept(v)
if !ok {
return n, false
}
n.Left = node.(ResultSetNode)
if n.Right != nil {
node, ok = n.Right.Accept(v)
if !ok {
return n, false
}
n.Right = node.(ResultSetNode)
}
if n.On != nil {
node, ok = n.On.Accept(v)
if !ok {
return n, false
}
n.On = node.(*OnCondition)
}
return v.Leave(n)
}
// TableName represents a table name.
type TableName struct {
node
resultSetNode
Schema model.CIStr
Name model.CIStr
DBInfo *model.DBInfo
TableInfo *model.TableInfo
}
// Accept implements Node Accept interface.
func (n *TableName) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*TableName)
return v.Leave(n)
}
// DeleteTableList is the tablelist used in delete statement multi-table mode.
type DeleteTableList struct {
node
Tables []*TableName
}
// Accept implements Node Accept interface.
func (n *DeleteTableList) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DeleteTableList)
if n != nil {
for i, t := range n.Tables {
node, ok := t.Accept(v)
if !ok {
return n, false
}
n.Tables[i] = node.(*TableName)
}
}
return v.Leave(n)
}
// OnCondition represetns JOIN on condition.
type OnCondition struct {
node
Expr ExprNode
}
// Accept implements Node Accept interface.
func (n *OnCondition) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*OnCondition)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// TableSource represents table source with a name.
type TableSource struct {
node
// Source is the source of the data, can be a TableName,
// a SelectStmt, a UnionStmt, or a JoinNode.
Source ResultSetNode
// AsName is the alias name of the table source.
AsName model.CIStr
}
// Accept implements Node Accept interface.
func (n *TableSource) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*TableSource)
node, ok := n.Source.Accept(v)
if !ok {
return n, false
}
n.Source = node.(ResultSetNode)
return v.Leave(n)
}
// SetResultFields implements ResultSetNode interface.
func (n *TableSource) SetResultFields(rfs []*ResultField) {
n.Source.SetResultFields(rfs)
}
// GetResultFields implements ResultSetNode interface.
func (n *TableSource) GetResultFields() []*ResultField {
return n.Source.GetResultFields()
}
// SelectLockType is the lock type for SelectStmt.
type SelectLockType int
// Select lock types.
const (
SelectLockNone SelectLockType = iota
SelectLockForUpdate
SelectLockInShareMode
)
// WildCardField is a special type of select field content.
type WildCardField struct {
node
Table model.CIStr
Schema model.CIStr
}
// Accept implements Node Accept interface.
func (n *WildCardField) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*WildCardField)
return v.Leave(n)
}
// SelectField represents fields in select statement.
// There are two type of select field: wildcard
// and expression with optional alias name.
type SelectField struct {
node
// Offset is used to get original text.
Offset int
// If WildCard is not nil, Expr will be nil.
WildCard *WildCardField
// If Expr is not nil, WildCard will be nil.
Expr ExprNode
// Alias name for Expr.
AsName model.CIStr
}
// Accept implements Node Accept interface.
func (n *SelectField) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*SelectField)
if n.Expr != nil {
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
}
return v.Leave(n)
}
// FieldList represents field list in select statement.
type FieldList struct {
node
Fields []*SelectField
}
// Accept implements Node Accept interface.
func (n *FieldList) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*FieldList)
for i, val := range n.Fields {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Fields[i] = node.(*SelectField)
}
return v.Leave(n)
}
// TableRefsClause represents table references clause in dml statement.
type TableRefsClause struct {
node
TableRefs *Join
}
// Accept implements Node Accept interface.
func (n *TableRefsClause) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*TableRefsClause)
node, ok := n.TableRefs.Accept(v)
if !ok {
return n, false
}
n.TableRefs = node.(*Join)
return v.Leave(n)
}
// ByItem represents an item in order by or group by.
type ByItem struct {
node
Expr ExprNode
Desc bool
}
// Accept implements Node Accept interface.
func (n *ByItem) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ByItem)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// GroupByClause represents group by clause.
type GroupByClause struct {
node
Items []*ByItem
}
// Accept implements Node Accept interface.
func (n *GroupByClause) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*GroupByClause)
for i, val := range n.Items {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Items[i] = node.(*ByItem)
}
return v.Leave(n)
}
// HavingClause represents having clause.
type HavingClause struct {
node
Expr ExprNode
}
// Accept implements Node Accept interface.
func (n *HavingClause) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*HavingClause)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// OrderByClause represents order by clause.
type OrderByClause struct {
node
Items []*ByItem
ForUnion bool
}
// Accept implements Node Accept interface.
func (n *OrderByClause) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*OrderByClause)
for i, val := range n.Items {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Items[i] = node.(*ByItem)
}
return v.Leave(n)
}
// SelectStmt represents the select query node.
// See: https://dev.mysql.com/doc/refman/5.7/en/select.html
type SelectStmt struct {
dmlNode
resultSetNode
// Distinct represents if the select has distinct option.
Distinct bool
// From is the from clause of the query.
From *TableRefsClause
// Where is the where clause in select statement.
Where ExprNode
// Fields is the select expression list.
Fields *FieldList
// GroupBy is the group by expression list.
GroupBy *GroupByClause
// Having is the having condition.
Having *HavingClause
// OrderBy is the ordering expression list.
OrderBy *OrderByClause
// Limit is the limit clause.
Limit *Limit
// Lock is the lock type
LockTp SelectLockType
}
// Accept implements Node Accept interface.
func (n *SelectStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*SelectStmt)
if n.From != nil {
node, ok := n.From.Accept(v)
if !ok {
return n, false
}
n.From = node.(*TableRefsClause)
}
if n.Where != nil {
node, ok := n.Where.Accept(v)
if !ok {
return n, false
}
n.Where = node.(ExprNode)
}
if n.Fields != nil {
node, ok := n.Fields.Accept(v)
if !ok {
return n, false
}
n.Fields = node.(*FieldList)
}
if n.GroupBy != nil {
node, ok := n.GroupBy.Accept(v)
if !ok {
return n, false
}
n.GroupBy = node.(*GroupByClause)
}
if n.Having != nil {
node, ok := n.Having.Accept(v)
if !ok {
return n, false
}
n.Having = node.(*HavingClause)
}
if n.OrderBy != nil {
node, ok := n.OrderBy.Accept(v)
if !ok {
return n, false
}
n.OrderBy = node.(*OrderByClause)
}
if n.Limit != nil {
node, ok := n.Limit.Accept(v)
if !ok {
return n, false
}
n.Limit = node.(*Limit)
}
return v.Leave(n)
}
// UnionSelectList represents the select list in a union statement.
type UnionSelectList struct {
node
Selects []*SelectStmt
}
// Accept implements Node Accept interface.
func (n *UnionSelectList) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*UnionSelectList)
for i, sel := range n.Selects {
node, ok := sel.Accept(v)
if !ok {
return n, false
}
n.Selects[i] = node.(*SelectStmt)
}
return v.Leave(n)
}
// UnionStmt represents "union statement"
// See: https://dev.mysql.com/doc/refman/5.7/en/union.html
type UnionStmt struct {
dmlNode
resultSetNode
Distinct bool
SelectList *UnionSelectList
OrderBy *OrderByClause
Limit *Limit
}
// Accept implements Node Accept interface.
func (n *UnionStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*UnionStmt)
if n.SelectList != nil {
node, ok := n.SelectList.Accept(v)
if !ok {
return n, false
}
n.SelectList = node.(*UnionSelectList)
}
if n.OrderBy != nil {
node, ok := n.OrderBy.Accept(v)
if !ok {
return n, false
}
n.OrderBy = node.(*OrderByClause)
}
if n.Limit != nil {
node, ok := n.Limit.Accept(v)
if !ok {
return n, false
}
n.Limit = node.(*Limit)
}
return v.Leave(n)
}
// Assignment is the expression for assignment, like a = 1.
type Assignment struct {
node
// Column is the column name to be assigned.
Column *ColumnName
// Expr is the expression assigning to ColName.
Expr ExprNode
}
// Accept implements Node Accept interface.
func (n *Assignment) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*Assignment)
node, ok := n.Column.Accept(v)
if !ok {
return n, false
}
n.Column = node.(*ColumnName)
node, ok = n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// Priority const values.
// See: https://dev.mysql.com/doc/refman/5.7/en/insert.html
const (
NoPriority = iota
LowPriority
HighPriority
DelayedPriority
)
// InsertStmt is a statement to insert new rows into an existing table.
// See: https://dev.mysql.com/doc/refman/5.7/en/insert.html
type InsertStmt struct {
dmlNode
IsReplace bool
Table *TableRefsClause
Columns []*ColumnName
Lists [][]ExprNode
Setlist []*Assignment
Priority int
OnDuplicate []*Assignment
Select ResultSetNode
}
// Accept implements Node Accept interface.
func (n *InsertStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*InsertStmt)
if n.Select != nil {
node, ok := n.Select.Accept(v)
if !ok {
return n, false
}
n.Select = node.(ResultSetNode)
}
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableRefsClause)
for i, val := range n.Columns {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Columns[i] = node.(*ColumnName)
}
for i, list := range n.Lists {
for j, val := range list {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Lists[i][j] = node.(ExprNode)
}
}
for i, val := range n.Setlist {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Setlist[i] = node.(*Assignment)
}
for i, val := range n.OnDuplicate {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.OnDuplicate[i] = node.(*Assignment)
}
return v.Leave(n)
}
// DeleteStmt is a statement to delete rows from table.
// See: https://dev.mysql.com/doc/refman/5.7/en/delete.html
type DeleteStmt struct {
dmlNode
// Used in both single table and multiple table delete statement.
TableRefs *TableRefsClause
// Only used in multiple table delete statement.
Tables *DeleteTableList
Where ExprNode
Order *OrderByClause
Limit *Limit
LowPriority bool
Ignore bool
Quick bool
IsMultiTable bool
BeforeFrom bool
}
// Accept implements Node Accept interface.
func (n *DeleteStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DeleteStmt)
node, ok := n.TableRefs.Accept(v)
if !ok {
return n, false
}
n.TableRefs = node.(*TableRefsClause)
node, ok = n.Tables.Accept(v)
if !ok {
return n, false
}
n.Tables = node.(*DeleteTableList)
if n.Where != nil {
node, ok = n.Where.Accept(v)
if !ok {
return n, false
}
n.Where = node.(ExprNode)
}
if n.Order != nil {
node, ok = n.Order.Accept(v)
if !ok {
return n, false
}
n.Order = node.(*OrderByClause)
}
if n.Limit != nil {
node, ok = n.Limit.Accept(v)
if !ok {
return n, false
}
n.Limit = node.(*Limit)
}
return v.Leave(n)
}
// UpdateStmt is a statement to update columns of existing rows in tables with new values.
// See: https://dev.mysql.com/doc/refman/5.7/en/update.html
type UpdateStmt struct {
dmlNode
TableRefs *TableRefsClause
List []*Assignment
Where ExprNode
Order *OrderByClause
Limit *Limit
LowPriority bool
Ignore bool
MultipleTable bool
}
// Accept implements Node Accept interface.
func (n *UpdateStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*UpdateStmt)
node, ok := n.TableRefs.Accept(v)
if !ok {
return n, false
}
n.TableRefs = node.(*TableRefsClause)
for i, val := range n.List {
node, ok = val.Accept(v)
if !ok {
return n, false
}
n.List[i] = node.(*Assignment)
}
if n.Where != nil {
node, ok = n.Where.Accept(v)
if !ok {
return n, false
}
n.Where = node.(ExprNode)
}
if n.Order != nil {
node, ok = n.Order.Accept(v)
if !ok {
return n, false
}
n.Order = node.(*OrderByClause)
}
if n.Limit != nil {
node, ok = n.Limit.Accept(v)
if !ok {
return n, false
}
n.Limit = node.(*Limit)
}
return v.Leave(n)
}
// Limit is the limit clause.
type Limit struct {
node
Offset uint64
Count uint64
}
// Accept implements Node Accept interface.
func (n *Limit) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*Limit)
return v.Leave(n)
}
// ShowStmtType is the type for SHOW statement.
type ShowStmtType int
// Show statement types.
const (
ShowNone = iota
ShowEngines
ShowDatabases
ShowTables
ShowTableStatus
ShowColumns
ShowWarnings
ShowCharset
ShowVariables
ShowStatus
ShowCollation
ShowCreateTable
ShowGrants
ShowTriggers
ShowProcedureStatus
ShowIndex
)
// ShowStmt is a statement to provide information about databases, tables, columns and so on.
// See: https://dev.mysql.com/doc/refman/5.7/en/show.html
type ShowStmt struct {
dmlNode
resultSetNode
Tp ShowStmtType // Databases/Tables/Columns/....
DBName string
Table *TableName // Used for showing columns.
Column *ColumnName // Used for `desc table column`.
Flag int // Some flag parsed from sql, such as FULL.
Full bool
User string // Used for show grants.
// Used by show variables
GlobalScope bool
Pattern *PatternLikeExpr
Where ExprNode
}
// Accept implements Node Accept interface.
func (n *ShowStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ShowStmt)
if n.Table != nil {
node, ok := n.Table.Accept(v)
if !ok {
return n, false
}
n.Table = node.(*TableName)
}
if n.Column != nil {
node, ok := n.Column.Accept(v)
if !ok {
return n, false
}
n.Column = node.(*ColumnName)
}
if n.Pattern != nil {
node, ok := n.Pattern.Accept(v)
if !ok {
return n, false
}
n.Pattern = node.(*PatternLikeExpr)
}
if n.Where != nil {
node, ok := n.Where.Accept(v)
if !ok {
return n, false
}
n.Where = node.(ExprNode)
}
return v.Leave(n)
}

749
vendor/github.com/pingcap/tidb/ast/expressions.go generated vendored Normal file
View file

@ -0,0 +1,749 @@
// 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 ast
import (
"regexp"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/parser/opcode"
"github.com/pingcap/tidb/util/types"
)
var (
_ ExprNode = &BetweenExpr{}
_ ExprNode = &BinaryOperationExpr{}
_ ExprNode = &CaseExpr{}
_ ExprNode = &ColumnNameExpr{}
_ ExprNode = &CompareSubqueryExpr{}
_ ExprNode = &DefaultExpr{}
_ ExprNode = &ExistsSubqueryExpr{}
_ ExprNode = &IsNullExpr{}
_ ExprNode = &IsTruthExpr{}
_ ExprNode = &ParamMarkerExpr{}
_ ExprNode = &ParenthesesExpr{}
_ ExprNode = &PatternInExpr{}
_ ExprNode = &PatternLikeExpr{}
_ ExprNode = &PatternRegexpExpr{}
_ ExprNode = &PositionExpr{}
_ ExprNode = &RowExpr{}
_ ExprNode = &SubqueryExpr{}
_ ExprNode = &UnaryOperationExpr{}
_ ExprNode = &ValueExpr{}
_ ExprNode = &ValuesExpr{}
_ ExprNode = &VariableExpr{}
_ Node = &ColumnName{}
_ Node = &WhenClause{}
)
// ValueExpr is the simple value expression.
type ValueExpr struct {
exprNode
}
// NewValueExpr creates a ValueExpr with value, and sets default field type.
func NewValueExpr(value interface{}) *ValueExpr {
if ve, ok := value.(*ValueExpr); ok {
return ve
}
ve := &ValueExpr{}
ve.SetValue(value)
if _, ok := value.(UnquoteString); ok {
ve.Type = types.NewFieldType(mysql.TypeVarchar)
ve.Type.Charset = mysql.DefaultCharset
ve.Type.Collate = mysql.DefaultCollationName
return ve
}
ve.Type = types.DefaultTypeForValue(value)
return ve
}
// Accept implements Node interface.
func (n *ValueExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ValueExpr)
return v.Leave(n)
}
// BetweenExpr is for "between and" or "not between and" expression.
type BetweenExpr struct {
exprNode
// Expr is the expression to be checked.
Expr ExprNode
// Left is the expression for minimal value in the range.
Left ExprNode
// Right is the expression for maximum value in the range.
Right ExprNode
// Not is true, the expression is "not between and".
Not bool
}
// Accept implements Node interface.
func (n *BetweenExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*BetweenExpr)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
node, ok = n.Left.Accept(v)
if !ok {
return n, false
}
n.Left = node.(ExprNode)
node, ok = n.Right.Accept(v)
if !ok {
return n, false
}
n.Right = node.(ExprNode)
return v.Leave(n)
}
// BinaryOperationExpr is for binary operation like `1 + 1`, `1 - 1`, etc.
type BinaryOperationExpr struct {
exprNode
// Op is the operator code for BinaryOperation.
Op opcode.Op
// L is the left expression in BinaryOperation.
L ExprNode
// R is the right expression in BinaryOperation.
R ExprNode
}
// Accept implements Node interface.
func (n *BinaryOperationExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*BinaryOperationExpr)
node, ok := n.L.Accept(v)
if !ok {
return n, false
}
n.L = node.(ExprNode)
node, ok = n.R.Accept(v)
if !ok {
return n, false
}
n.R = node.(ExprNode)
return v.Leave(n)
}
// WhenClause is the when clause in Case expression for "when condition then result".
type WhenClause struct {
node
// Expr is the condition expression in WhenClause.
Expr ExprNode
// Result is the result expression in WhenClause.
Result ExprNode
}
// Accept implements Node Accept interface.
func (n *WhenClause) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*WhenClause)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
node, ok = n.Result.Accept(v)
if !ok {
return n, false
}
n.Result = node.(ExprNode)
return v.Leave(n)
}
// CaseExpr is the case expression.
type CaseExpr struct {
exprNode
// Value is the compare value expression.
Value ExprNode
// WhenClauses is the condition check expression.
WhenClauses []*WhenClause
// ElseClause is the else result expression.
ElseClause ExprNode
}
// Accept implements Node Accept interface.
func (n *CaseExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*CaseExpr)
if n.Value != nil {
node, ok := n.Value.Accept(v)
if !ok {
return n, false
}
n.Value = node.(ExprNode)
}
for i, val := range n.WhenClauses {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.WhenClauses[i] = node.(*WhenClause)
}
if n.ElseClause != nil {
node, ok := n.ElseClause.Accept(v)
if !ok {
return n, false
}
n.ElseClause = node.(ExprNode)
}
return v.Leave(n)
}
// SubqueryExec represents a subquery executor interface.
// This interface is implemented in executor and used in plan/evaluator.
// It will execute the subselect and get the result.
type SubqueryExec interface {
ExprNode
// EvalRows executes the subquery and returns the multi rows with rowCount.
// rowCount < 0 means no limit.
// If the ColumnCount is 1, we will return a column result like {1, 2, 3},
// otherwise, we will return a table result like {{1, 1}, {2, 2}}.
EvalRows(ctx context.Context, rowCount int) ([]interface{}, error)
// ColumnCount returns column count for the sub query.
ColumnCount() (int, error)
}
// SubqueryExpr represents a subquery.
type SubqueryExpr struct {
exprNode
// Query is the query SelectNode.
Query ResultSetNode
SubqueryExec SubqueryExec
Evaluated bool
UseOuterContext bool
}
// Accept implements Node Accept interface.
func (n *SubqueryExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*SubqueryExpr)
if n.SubqueryExec != nil {
t, ok := n.SubqueryExec.Accept(v)
if !ok {
return n, false
}
sq, ok := t.(SubqueryExec)
if !ok {
return n, false
}
n.SubqueryExec = sq
return v.Leave(n)
}
node, ok := n.Query.Accept(v)
if !ok {
return n, false
}
n.Query = node.(ResultSetNode)
return v.Leave(n)
}
// SetResultFields implements ResultSetNode interface.
func (n *SubqueryExpr) SetResultFields(rfs []*ResultField) {
n.Query.SetResultFields(rfs)
}
// GetResultFields implements ResultSetNode interface.
func (n *SubqueryExpr) GetResultFields() []*ResultField {
return n.Query.GetResultFields()
}
// CompareSubqueryExpr is the expression for "expr cmp (select ...)".
// See: https://dev.mysql.com/doc/refman/5.7/en/comparisons-using-subqueries.html
// See: https://dev.mysql.com/doc/refman/5.7/en/any-in-some-subqueries.html
// See: https://dev.mysql.com/doc/refman/5.7/en/all-subqueries.html
type CompareSubqueryExpr struct {
exprNode
// L is the left expression
L ExprNode
// Op is the comparison opcode.
Op opcode.Op
// R is the subquery for right expression, may be rewritten to other type of expression.
R ExprNode
// All is true, we should compare all records in subquery.
All bool
}
// Accept implements Node Accept interface.
func (n *CompareSubqueryExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*CompareSubqueryExpr)
node, ok := n.L.Accept(v)
if !ok {
return n, false
}
n.L = node.(ExprNode)
node, ok = n.R.Accept(v)
if !ok {
return n, false
}
n.R = node.(ExprNode)
return v.Leave(n)
}
// ColumnName represents column name.
type ColumnName struct {
node
Schema model.CIStr
Table model.CIStr
Name model.CIStr
}
// Accept implements Node Accept interface.
func (n *ColumnName) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ColumnName)
return v.Leave(n)
}
// ColumnNameExpr represents a column name expression.
type ColumnNameExpr struct {
exprNode
// Name is the referenced column name.
Name *ColumnName
// Refer is the result field the column name refers to.
// The value of Refer.Expr is used as the value of the expression.
Refer *ResultField
}
// Accept implements Node Accept interface.
func (n *ColumnNameExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ColumnNameExpr)
node, ok := n.Name.Accept(v)
if !ok {
return n, false
}
n.Name = node.(*ColumnName)
return v.Leave(n)
}
// DefaultExpr is the default expression using default value for a column.
type DefaultExpr struct {
exprNode
// Name is the column name.
Name *ColumnName
}
// Accept implements Node Accept interface.
func (n *DefaultExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DefaultExpr)
if n.Name != nil {
node, ok := n.Name.Accept(v)
if !ok {
return n, false
}
n.Name = node.(*ColumnName)
}
return v.Leave(n)
}
// ExistsSubqueryExpr is the expression for "exists (select ...)".
// https://dev.mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html
type ExistsSubqueryExpr struct {
exprNode
// Sel is the subquery, may be rewritten to other type of expression.
Sel ExprNode
}
// Accept implements Node Accept interface.
func (n *ExistsSubqueryExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ExistsSubqueryExpr)
node, ok := n.Sel.Accept(v)
if !ok {
return n, false
}
n.Sel = node.(ExprNode)
return v.Leave(n)
}
// PatternInExpr is the expression for in operator, like "expr in (1, 2, 3)" or "expr in (select c from t)".
type PatternInExpr struct {
exprNode
// Expr is the value expression to be compared.
Expr ExprNode
// List is the list expression in compare list.
List []ExprNode
// Not is true, the expression is "not in".
Not bool
// Sel is the subquery, may be rewritten to other type of expression.
Sel ExprNode
}
// Accept implements Node Accept interface.
func (n *PatternInExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*PatternInExpr)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
for i, val := range n.List {
node, ok = val.Accept(v)
if !ok {
return n, false
}
n.List[i] = node.(ExprNode)
}
if n.Sel != nil {
node, ok = n.Sel.Accept(v)
if !ok {
return n, false
}
n.Sel = node.(ExprNode)
}
return v.Leave(n)
}
// IsNullExpr is the expression for null check.
type IsNullExpr struct {
exprNode
// Expr is the expression to be checked.
Expr ExprNode
// Not is true, the expression is "is not null".
Not bool
}
// Accept implements Node Accept interface.
func (n *IsNullExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*IsNullExpr)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// IsTruthExpr is the expression for true/false check.
type IsTruthExpr struct {
exprNode
// Expr is the expression to be checked.
Expr ExprNode
// Not is true, the expression is "is not true/false".
Not bool
// True indicates checking true or false.
True int64
}
// Accept implements Node Accept interface.
func (n *IsTruthExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*IsTruthExpr)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// PatternLikeExpr is the expression for like operator, e.g, expr like "%123%"
type PatternLikeExpr struct {
exprNode
// Expr is the expression to be checked.
Expr ExprNode
// Pattern is the like expression.
Pattern ExprNode
// Not is true, the expression is "not like".
Not bool
Escape byte
PatChars []byte
PatTypes []byte
}
// Accept implements Node Accept interface.
func (n *PatternLikeExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*PatternLikeExpr)
if n.Expr != nil {
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
}
if n.Pattern != nil {
node, ok := n.Pattern.Accept(v)
if !ok {
return n, false
}
n.Pattern = node.(ExprNode)
}
return v.Leave(n)
}
// ParamMarkerExpr expression holds a place for another expression.
// Used in parsing prepare statement.
type ParamMarkerExpr struct {
exprNode
Offset int
}
// Accept implements Node Accept interface.
func (n *ParamMarkerExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ParamMarkerExpr)
return v.Leave(n)
}
// ParenthesesExpr is the parentheses expression.
type ParenthesesExpr struct {
exprNode
// Expr is the expression in parentheses.
Expr ExprNode
}
// Accept implements Node Accept interface.
func (n *ParenthesesExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ParenthesesExpr)
if n.Expr != nil {
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
}
return v.Leave(n)
}
// PositionExpr is the expression for order by and group by position.
// MySQL use position expression started from 1, it looks a little confused inner.
// maybe later we will use 0 at first.
type PositionExpr struct {
exprNode
// N is the position, started from 1 now.
N int
// Refer is the result field the position refers to.
Refer *ResultField
}
// Accept implements Node Accept interface.
func (n *PositionExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*PositionExpr)
return v.Leave(n)
}
// PatternRegexpExpr is the pattern expression for pattern match.
type PatternRegexpExpr struct {
exprNode
// Expr is the expression to be checked.
Expr ExprNode
// Pattern is the expression for pattern.
Pattern ExprNode
// Not is true, the expression is "not rlike",
Not bool
// Re is the compiled regexp.
Re *regexp.Regexp
// Sexpr is the string for Expr expression.
Sexpr *string
}
// Accept implements Node Accept interface.
func (n *PatternRegexpExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*PatternRegexpExpr)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
node, ok = n.Pattern.Accept(v)
if !ok {
return n, false
}
n.Pattern = node.(ExprNode)
return v.Leave(n)
}
// RowExpr is the expression for row constructor.
// See https://dev.mysql.com/doc/refman/5.7/en/row-subqueries.html
type RowExpr struct {
exprNode
Values []ExprNode
}
// Accept implements Node Accept interface.
func (n *RowExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*RowExpr)
for i, val := range n.Values {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Values[i] = node.(ExprNode)
}
return v.Leave(n)
}
// UnaryOperationExpr is the expression for unary operator.
type UnaryOperationExpr struct {
exprNode
// Op is the operator opcode.
Op opcode.Op
// V is the unary expression.
V ExprNode
}
// Accept implements Node Accept interface.
func (n *UnaryOperationExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*UnaryOperationExpr)
node, ok := n.V.Accept(v)
if !ok {
return n, false
}
n.V = node.(ExprNode)
return v.Leave(n)
}
// ValuesExpr is the expression used in INSERT VALUES
type ValuesExpr struct {
exprNode
// model.CIStr is column name.
Column *ColumnNameExpr
}
// Accept implements Node Accept interface.
func (n *ValuesExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ValuesExpr)
node, ok := n.Column.Accept(v)
if !ok {
return n, false
}
n.Column = node.(*ColumnNameExpr)
return v.Leave(n)
}
// VariableExpr is the expression for variable.
type VariableExpr struct {
exprNode
// Name is the variable name.
Name string
// IsGlobal indicates whether this variable is global.
IsGlobal bool
// IsSystem indicates whether this variable is a system variable in current session.
IsSystem bool
}
// Accept implements Node Accept interface.
func (n *VariableExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*VariableExpr)
return v.Leave(n)
}

165
vendor/github.com/pingcap/tidb/ast/flag.go generated vendored Normal file
View file

@ -0,0 +1,165 @@
// 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 ast
const preEvaluable = FlagHasParamMarker | FlagHasFunc | FlagHasVariable | FlagHasDefault
// IsPreEvaluable checks if the expression can be evaluated before execution.
func IsPreEvaluable(expr ExprNode) bool {
return expr.GetFlag()|preEvaluable == preEvaluable
}
// IsConstant checks if the expression is constant.
// A constant expression is safe to be rewritten to value expression.
func IsConstant(expr ExprNode) bool {
return expr.GetFlag() == FlagConstant
}
// HasAggFlag checks if the expr contains FlagHasAggregateFunc.
func HasAggFlag(expr ExprNode) bool {
return expr.GetFlag()&FlagHasAggregateFunc > 0
}
// SetFlag sets flag for expression.
func SetFlag(n Node) {
var setter flagSetter
n.Accept(&setter)
}
type flagSetter struct {
}
func (f *flagSetter) Enter(in Node) (Node, bool) {
return in, false
}
func (f *flagSetter) Leave(in Node) (Node, bool) {
switch x := in.(type) {
case *AggregateFuncExpr:
f.aggregateFunc(x)
case *BetweenExpr:
x.SetFlag(x.Expr.GetFlag() | x.Left.GetFlag() | x.Right.GetFlag())
case *BinaryOperationExpr:
x.SetFlag(x.L.GetFlag() | x.R.GetFlag())
case *CaseExpr:
f.caseExpr(x)
case *ColumnNameExpr:
x.SetFlag(FlagHasReference)
case *CompareSubqueryExpr:
x.SetFlag(x.L.GetFlag() | x.R.GetFlag())
case *DefaultExpr:
x.SetFlag(FlagHasDefault)
case *ExistsSubqueryExpr:
x.SetFlag(x.Sel.GetFlag())
case *FuncCallExpr:
f.funcCall(x)
case *FuncCastExpr:
x.SetFlag(FlagHasFunc | x.Expr.GetFlag())
case *IsNullExpr:
x.SetFlag(x.Expr.GetFlag())
case *IsTruthExpr:
x.SetFlag(x.Expr.GetFlag())
case *ParamMarkerExpr:
x.SetFlag(FlagHasParamMarker)
case *ParenthesesExpr:
x.SetFlag(x.Expr.GetFlag())
case *PatternInExpr:
f.patternIn(x)
case *PatternLikeExpr:
f.patternLike(x)
case *PatternRegexpExpr:
f.patternRegexp(x)
case *PositionExpr:
x.SetFlag(FlagHasReference)
case *RowExpr:
f.row(x)
case *SubqueryExpr:
x.SetFlag(FlagHasSubquery)
case *UnaryOperationExpr:
x.SetFlag(x.V.GetFlag())
case *ValueExpr:
case *ValuesExpr:
x.SetFlag(FlagHasReference)
case *VariableExpr:
x.SetFlag(FlagHasVariable)
}
return in, true
}
func (f *flagSetter) caseExpr(x *CaseExpr) {
var flag uint64
if x.Value != nil {
flag |= x.Value.GetFlag()
}
for _, val := range x.WhenClauses {
flag |= val.Expr.GetFlag()
flag |= val.Result.GetFlag()
}
if x.ElseClause != nil {
flag |= x.ElseClause.GetFlag()
}
x.SetFlag(flag)
}
func (f *flagSetter) patternIn(x *PatternInExpr) {
flag := x.Expr.GetFlag()
for _, val := range x.List {
flag |= val.GetFlag()
}
if x.Sel != nil {
flag |= x.Sel.GetFlag()
}
x.SetFlag(flag)
}
func (f *flagSetter) patternLike(x *PatternLikeExpr) {
flag := x.Pattern.GetFlag()
if x.Expr != nil {
flag |= x.Expr.GetFlag()
}
x.SetFlag(flag)
}
func (f *flagSetter) patternRegexp(x *PatternRegexpExpr) {
flag := x.Pattern.GetFlag()
if x.Expr != nil {
flag |= x.Expr.GetFlag()
}
x.SetFlag(flag)
}
func (f *flagSetter) row(x *RowExpr) {
var flag uint64
for _, val := range x.Values {
flag |= val.GetFlag()
}
x.SetFlag(flag)
}
func (f *flagSetter) funcCall(x *FuncCallExpr) {
flag := FlagHasFunc
for _, val := range x.Args {
flag |= val.GetFlag()
}
x.SetFlag(flag)
}
func (f *flagSetter) aggregateFunc(x *AggregateFuncExpr) {
flag := FlagHasAggregateFunc
for _, val := range x.Args {
flag |= val.GetFlag()
}
x.SetFlag(flag)
}

403
vendor/github.com/pingcap/tidb/ast/functions.go generated vendored Normal file
View file

@ -0,0 +1,403 @@
// 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 ast
import (
"bytes"
"fmt"
"strings"
"github.com/juju/errors"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/util/distinct"
"github.com/pingcap/tidb/util/types"
)
var (
_ FuncNode = &AggregateFuncExpr{}
_ FuncNode = &FuncCallExpr{}
_ FuncNode = &FuncCastExpr{}
)
// UnquoteString is not quoted when printed.
type UnquoteString string
// FuncCallExpr is for function expression.
type FuncCallExpr struct {
funcNode
// FnName is the function name.
FnName model.CIStr
// Args is the function args.
Args []ExprNode
}
// Accept implements Node interface.
func (n *FuncCallExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*FuncCallExpr)
for i, val := range n.Args {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Args[i] = node.(ExprNode)
}
return v.Leave(n)
}
// CastFunctionType is the type for cast function.
type CastFunctionType int
// CastFunction types
const (
CastFunction CastFunctionType = iota + 1
CastConvertFunction
CastBinaryOperator
)
// FuncCastExpr is the cast function converting value to another type, e.g, cast(expr AS signed).
// See https://dev.mysql.com/doc/refman/5.7/en/cast-functions.html
type FuncCastExpr struct {
funcNode
// Expr is the expression to be converted.
Expr ExprNode
// Tp is the conversion type.
Tp *types.FieldType
// Cast, Convert and Binary share this struct.
FunctionType CastFunctionType
}
// Accept implements Node Accept interface.
func (n *FuncCastExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*FuncCastExpr)
node, ok := n.Expr.Accept(v)
if !ok {
return n, false
}
n.Expr = node.(ExprNode)
return v.Leave(n)
}
// TrimDirectionType is the type for trim direction.
type TrimDirectionType int
const (
// TrimBothDefault trims from both direction by default.
TrimBothDefault TrimDirectionType = iota
// TrimBoth trims from both direction with explicit notation.
TrimBoth
// TrimLeading trims from left.
TrimLeading
// TrimTrailing trims from right.
TrimTrailing
)
// DateArithType is type for DateArith type.
type DateArithType byte
const (
// DateAdd is to run adddate or date_add function option.
// See: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_adddate
// See: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-add
DateAdd DateArithType = iota + 1
// DateSub is to run subdate or date_sub function option.
// See: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_subdate
// See: https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html#function_date-sub
DateSub
)
// DateArithInterval is the struct of DateArith interval part.
type DateArithInterval struct {
Unit string
Interval ExprNode
}
const (
// AggFuncCount is the name of Count function.
AggFuncCount = "count"
// AggFuncSum is the name of Sum function.
AggFuncSum = "sum"
// AggFuncAvg is the name of Avg function.
AggFuncAvg = "avg"
// AggFuncFirstRow is the name of FirstRowColumn function.
AggFuncFirstRow = "firstrow"
// AggFuncMax is the name of max function.
AggFuncMax = "max"
// AggFuncMin is the name of min function.
AggFuncMin = "min"
// AggFuncGroupConcat is the name of group_concat function.
AggFuncGroupConcat = "group_concat"
)
// AggregateFuncExpr represents aggregate function expression.
type AggregateFuncExpr struct {
funcNode
// F is the function name.
F string
// Args is the function args.
Args []ExprNode
// If distinct is true, the function only aggregate distinct values.
// For example, column c1 values are "1", "2", "2", "sum(c1)" is "5",
// but "sum(distinct c1)" is "3".
Distinct bool
CurrentGroup string
// contextPerGroupMap is used to store aggregate evaluation context.
// Each entry for a group.
contextPerGroupMap map[string](*AggEvaluateContext)
}
// Accept implements Node Accept interface.
func (n *AggregateFuncExpr) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*AggregateFuncExpr)
for i, val := range n.Args {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Args[i] = node.(ExprNode)
}
return v.Leave(n)
}
// Clear clears aggregate computing context.
func (n *AggregateFuncExpr) Clear() {
n.CurrentGroup = ""
n.contextPerGroupMap = nil
}
// Update is used for update aggregate context.
func (n *AggregateFuncExpr) Update() error {
name := strings.ToLower(n.F)
switch name {
case AggFuncCount:
return n.updateCount()
case AggFuncFirstRow:
return n.updateFirstRow()
case AggFuncGroupConcat:
return n.updateGroupConcat()
case AggFuncMax:
return n.updateMaxMin(true)
case AggFuncMin:
return n.updateMaxMin(false)
case AggFuncSum, AggFuncAvg:
return n.updateSum()
}
return nil
}
// GetContext gets aggregate evaluation context for the current group.
// If it is nil, add a new context into contextPerGroupMap.
func (n *AggregateFuncExpr) GetContext() *AggEvaluateContext {
if n.contextPerGroupMap == nil {
n.contextPerGroupMap = make(map[string](*AggEvaluateContext))
}
if _, ok := n.contextPerGroupMap[n.CurrentGroup]; !ok {
c := &AggEvaluateContext{}
if n.Distinct {
c.distinctChecker = distinct.CreateDistinctChecker()
}
n.contextPerGroupMap[n.CurrentGroup] = c
}
return n.contextPerGroupMap[n.CurrentGroup]
}
func (n *AggregateFuncExpr) updateCount() error {
ctx := n.GetContext()
vals := make([]interface{}, 0, len(n.Args))
for _, a := range n.Args {
value := a.GetValue()
if value == nil {
return nil
}
vals = append(vals, value)
}
if n.Distinct {
d, err := ctx.distinctChecker.Check(vals)
if err != nil {
return errors.Trace(err)
}
if !d {
return nil
}
}
ctx.Count++
return nil
}
func (n *AggregateFuncExpr) updateFirstRow() error {
ctx := n.GetContext()
if ctx.evaluated {
return nil
}
if len(n.Args) != 1 {
return errors.New("Wrong number of args for AggFuncFirstRow")
}
ctx.Value = n.Args[0].GetValue()
ctx.evaluated = true
return nil
}
func (n *AggregateFuncExpr) updateMaxMin(max bool) error {
ctx := n.GetContext()
if len(n.Args) != 1 {
return errors.New("Wrong number of args for AggFuncFirstRow")
}
v := n.Args[0].GetValue()
if !ctx.evaluated {
ctx.Value = v
ctx.evaluated = true
return nil
}
c, err := types.Compare(ctx.Value, v)
if err != nil {
return errors.Trace(err)
}
if max {
if c == -1 {
ctx.Value = v
}
} else {
if c == 1 {
ctx.Value = v
}
}
return nil
}
func (n *AggregateFuncExpr) updateSum() error {
ctx := n.GetContext()
a := n.Args[0]
value := a.GetValue()
if value == nil {
return nil
}
if n.Distinct {
d, err := ctx.distinctChecker.Check([]interface{}{value})
if err != nil {
return errors.Trace(err)
}
if !d {
return nil
}
}
var err error
ctx.Value, err = types.CalculateSum(ctx.Value, value)
if err != nil {
return errors.Trace(err)
}
ctx.Count++
return nil
}
func (n *AggregateFuncExpr) updateGroupConcat() error {
ctx := n.GetContext()
vals := make([]interface{}, 0, len(n.Args))
for _, a := range n.Args {
value := a.GetValue()
if value == nil {
return nil
}
vals = append(vals, value)
}
if n.Distinct {
d, err := ctx.distinctChecker.Check(vals)
if err != nil {
return errors.Trace(err)
}
if !d {
return nil
}
}
if ctx.Buffer == nil {
ctx.Buffer = &bytes.Buffer{}
} else {
// now use comma separator
ctx.Buffer.WriteString(",")
}
for _, val := range vals {
ctx.Buffer.WriteString(fmt.Sprintf("%v", val))
}
// TODO: if total length is greater than global var group_concat_max_len, truncate it.
return nil
}
// AggregateFuncExtractor visits Expr tree.
// It converts ColunmNameExpr to AggregateFuncExpr and collects AggregateFuncExpr.
type AggregateFuncExtractor struct {
inAggregateFuncExpr bool
// AggFuncs is the collected AggregateFuncExprs.
AggFuncs []*AggregateFuncExpr
extracting bool
}
// Enter implements Visitor interface.
func (a *AggregateFuncExtractor) Enter(n Node) (node Node, skipChildren bool) {
switch n.(type) {
case *AggregateFuncExpr:
a.inAggregateFuncExpr = true
case *SelectStmt, *InsertStmt, *DeleteStmt, *UpdateStmt:
// Enter a new context, skip it.
// For example: select sum(c) + c + exists(select c from t) from t;
if a.extracting {
return n, true
}
}
a.extracting = true
return n, false
}
// Leave implements Visitor interface.
func (a *AggregateFuncExtractor) Leave(n Node) (node Node, ok bool) {
switch v := n.(type) {
case *AggregateFuncExpr:
a.inAggregateFuncExpr = false
a.AggFuncs = append(a.AggFuncs, v)
case *ColumnNameExpr:
// compose new AggregateFuncExpr
if !a.inAggregateFuncExpr {
// For example: select sum(c) + c from t;
// The c in sum() should be evaluated for each row.
// The c after plus should be evaluated only once.
agg := &AggregateFuncExpr{
F: AggFuncFirstRow,
Args: []ExprNode{v},
}
a.AggFuncs = append(a.AggFuncs, agg)
return agg, true
}
}
return n, true
}
// AggEvaluateContext is used to store intermediate result when caculation aggregate functions.
type AggEvaluateContext struct {
distinctChecker *distinct.Checker
Count int64
Value interface{}
Buffer *bytes.Buffer // Buffer is used for group_concat.
evaluated bool
}

507
vendor/github.com/pingcap/tidb/ast/misc.go generated vendored Normal file
View file

@ -0,0 +1,507 @@
// 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 ast
import (
"fmt"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx/db"
)
var (
_ StmtNode = &AdminStmt{}
_ StmtNode = &BeginStmt{}
_ StmtNode = &CommitStmt{}
_ StmtNode = &CreateUserStmt{}
_ StmtNode = &DeallocateStmt{}
_ StmtNode = &DoStmt{}
_ StmtNode = &ExecuteStmt{}
_ StmtNode = &ExplainStmt{}
_ StmtNode = &GrantStmt{}
_ StmtNode = &PrepareStmt{}
_ StmtNode = &RollbackStmt{}
_ StmtNode = &SetCharsetStmt{}
_ StmtNode = &SetPwdStmt{}
_ StmtNode = &SetStmt{}
_ StmtNode = &UseStmt{}
_ Node = &PrivElem{}
_ Node = &VariableAssignment{}
)
// TypeOpt is used for parsing data type option from SQL.
type TypeOpt struct {
IsUnsigned bool
IsZerofill bool
}
// FloatOpt is used for parsing floating-point type option from SQL.
// See: http://dev.mysql.com/doc/refman/5.7/en/floating-point-types.html
type FloatOpt struct {
Flen int
Decimal int
}
// AuthOption is used for parsing create use statement.
type AuthOption struct {
// AuthString/HashString can be empty, so we need to decide which one to use.
ByAuthString bool
AuthString string
HashString string
// TODO: support auth_plugin
}
// ExplainStmt is a statement to provide information about how is SQL statement executed
// or get columns information in a table.
// See: https://dev.mysql.com/doc/refman/5.7/en/explain.html
type ExplainStmt struct {
stmtNode
Stmt StmtNode
}
// Accept implements Node Accept interface.
func (n *ExplainStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ExplainStmt)
node, ok := n.Stmt.Accept(v)
if !ok {
return n, false
}
n.Stmt = node.(DMLNode)
return v.Leave(n)
}
// PrepareStmt is a statement to prepares a SQL statement which contains placeholders,
// and it is executed with ExecuteStmt and released with DeallocateStmt.
// See: https://dev.mysql.com/doc/refman/5.7/en/prepare.html
type PrepareStmt struct {
stmtNode
Name string
SQLText string
SQLVar *VariableExpr
}
// Accept implements Node Accept interface.
func (n *PrepareStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*PrepareStmt)
if n.SQLVar != nil {
node, ok := n.SQLVar.Accept(v)
if !ok {
return n, false
}
n.SQLVar = node.(*VariableExpr)
}
return v.Leave(n)
}
// DeallocateStmt is a statement to release PreparedStmt.
// See: https://dev.mysql.com/doc/refman/5.7/en/deallocate-prepare.html
type DeallocateStmt struct {
stmtNode
Name string
}
// Accept implements Node Accept interface.
func (n *DeallocateStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DeallocateStmt)
return v.Leave(n)
}
// ExecuteStmt is a statement to execute PreparedStmt.
// See: https://dev.mysql.com/doc/refman/5.7/en/execute.html
type ExecuteStmt struct {
stmtNode
Name string
UsingVars []ExprNode
}
// Accept implements Node Accept interface.
func (n *ExecuteStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*ExecuteStmt)
for i, val := range n.UsingVars {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.UsingVars[i] = node.(ExprNode)
}
return v.Leave(n)
}
// BeginStmt is a statement to start a new transaction.
// See: https://dev.mysql.com/doc/refman/5.7/en/commit.html
type BeginStmt struct {
stmtNode
}
// Accept implements Node Accept interface.
func (n *BeginStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*BeginStmt)
return v.Leave(n)
}
// CommitStmt is a statement to commit the current transaction.
// See: https://dev.mysql.com/doc/refman/5.7/en/commit.html
type CommitStmt struct {
stmtNode
}
// Accept implements Node Accept interface.
func (n *CommitStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*CommitStmt)
return v.Leave(n)
}
// RollbackStmt is a statement to roll back the current transaction.
// See: https://dev.mysql.com/doc/refman/5.7/en/commit.html
type RollbackStmt struct {
stmtNode
}
// Accept implements Node Accept interface.
func (n *RollbackStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*RollbackStmt)
return v.Leave(n)
}
// UseStmt is a statement to use the DBName database as the current database.
// See: https://dev.mysql.com/doc/refman/5.7/en/use.html
type UseStmt struct {
stmtNode
DBName string
}
// Accept implements Node Accept interface.
func (n *UseStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*UseStmt)
return v.Leave(n)
}
// VariableAssignment is a variable assignment struct.
type VariableAssignment struct {
node
Name string
Value ExprNode
IsGlobal bool
IsSystem bool
}
// Accept implements Node interface.
func (n *VariableAssignment) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*VariableAssignment)
node, ok := n.Value.Accept(v)
if !ok {
return n, false
}
n.Value = node.(ExprNode)
return v.Leave(n)
}
// SetStmt is the statement to set variables.
type SetStmt struct {
stmtNode
// Variables is the list of variable assignment.
Variables []*VariableAssignment
}
// Accept implements Node Accept interface.
func (n *SetStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*SetStmt)
for i, val := range n.Variables {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Variables[i] = node.(*VariableAssignment)
}
return v.Leave(n)
}
// SetCharsetStmt is a statement to assign values to character and collation variables.
// See: https://dev.mysql.com/doc/refman/5.7/en/set-statement.html
type SetCharsetStmt struct {
stmtNode
Charset string
Collate string
}
// Accept implements Node Accept interface.
func (n *SetCharsetStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*SetCharsetStmt)
return v.Leave(n)
}
// SetPwdStmt is a statement to assign a password to user account.
// See: https://dev.mysql.com/doc/refman/5.7/en/set-password.html
type SetPwdStmt struct {
stmtNode
User string
Password string
}
// Accept implements Node Accept interface.
func (n *SetPwdStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*SetPwdStmt)
return v.Leave(n)
}
// UserSpec is used for parsing create user statement.
type UserSpec struct {
User string
AuthOpt *AuthOption
}
// CreateUserStmt creates user account.
// See: https://dev.mysql.com/doc/refman/5.7/en/create-user.html
type CreateUserStmt struct {
stmtNode
IfNotExists bool
Specs []*UserSpec
}
// Accept implements Node Accept interface.
func (n *CreateUserStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*CreateUserStmt)
return v.Leave(n)
}
// DoStmt is the struct for DO statement.
type DoStmt struct {
stmtNode
Exprs []ExprNode
}
// Accept implements Node Accept interface.
func (n *DoStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*DoStmt)
for i, val := range n.Exprs {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Exprs[i] = node.(ExprNode)
}
return v.Leave(n)
}
// AdminStmtType is the type for admin statement.
type AdminStmtType int
// Admin statement types.
const (
AdminShowDDL = iota + 1
AdminCheckTable
)
// AdminStmt is the struct for Admin statement.
type AdminStmt struct {
stmtNode
Tp AdminStmtType
Tables []*TableName
}
// Accept implements Node Accpet interface.
func (n *AdminStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*AdminStmt)
for i, val := range n.Tables {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Tables[i] = node.(*TableName)
}
return v.Leave(n)
}
// PrivElem is the privilege type and optional column list.
type PrivElem struct {
node
Priv mysql.PrivilegeType
Cols []*ColumnName
}
// Accept implements Node Accept interface.
func (n *PrivElem) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*PrivElem)
for i, val := range n.Cols {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Cols[i] = node.(*ColumnName)
}
return v.Leave(n)
}
// ObjectTypeType is the type for object type.
type ObjectTypeType int
const (
// ObjectTypeNone is for empty object type.
ObjectTypeNone ObjectTypeType = iota + 1
// ObjectTypeTable means the following object is a table.
ObjectTypeTable
)
// GrantLevelType is the type for grant level.
type GrantLevelType int
const (
// GrantLevelNone is the dummy const for default value.
GrantLevelNone GrantLevelType = iota + 1
// GrantLevelGlobal means the privileges are administrative or apply to all databases on a given server.
GrantLevelGlobal
// GrantLevelDB means the privileges apply to all objects in a given database.
GrantLevelDB
// GrantLevelTable means the privileges apply to all columns in a given table.
GrantLevelTable
)
// GrantLevel is used for store the privilege scope.
type GrantLevel struct {
Level GrantLevelType
DBName string
TableName string
}
// GrantStmt is the struct for GRANT statement.
type GrantStmt struct {
stmtNode
Privs []*PrivElem
ObjectType ObjectTypeType
Level *GrantLevel
Users []*UserSpec
}
// Accept implements Node Accept interface.
func (n *GrantStmt) Accept(v Visitor) (Node, bool) {
newNode, skipChildren := v.Enter(n)
if skipChildren {
return v.Leave(newNode)
}
n = newNode.(*GrantStmt)
for i, val := range n.Privs {
node, ok := val.Accept(v)
if !ok {
return n, false
}
n.Privs[i] = node.(*PrivElem)
}
return v.Leave(n)
}
// Ident is the table identifier composed of schema name and table name.
type Ident struct {
Schema model.CIStr
Name model.CIStr
}
// Full returns an Ident which set schema to the current schema if it is empty.
func (i Ident) Full(ctx context.Context) (full Ident) {
full.Name = i.Name
if i.Schema.O != "" {
full.Schema = i.Schema
} else {
full.Schema = model.NewCIStr(db.GetCurrentSchema(ctx))
}
return
}
// String implements fmt.Stringer interface
func (i Ident) String() string {
if i.Schema.O == "" {
return i.Name.O
}
return fmt.Sprintf("%s.%s", i.Schema, i.Name)
}

57
vendor/github.com/pingcap/tidb/ast/stringer.go generated vendored Normal file
View file

@ -0,0 +1,57 @@
// 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 ast
import (
"fmt"
"github.com/pingcap/tidb/util/types"
)
// ToString converts a node to a string for debugging purpose.
func ToString(node Node) string {
s := &stringer{strMap: map[Node]string{}}
node.Accept(s)
return s.strMap[node]
}
type stringer struct {
strMap map[Node]string
}
// Enter implements Visitor Enter interface.
func (c *stringer) Enter(node Node) (Node, bool) {
return node, false
}
// Leave implements Visitor Leave interface.
func (c *stringer) Leave(in Node) (out Node, ok bool) {
switch x := in.(type) {
case *BinaryOperationExpr:
left := c.strMap[x.L]
right := c.strMap[x.R]
c.strMap[x] = left + " " + x.Op.String() + " " + right
case *ValueExpr:
str, _ := types.ToString(x.GetValue())
c.strMap[x] = str
case *ParenthesesExpr:
c.strMap[x] = "(" + c.strMap[x.Expr] + ")"
case *ColumnNameExpr:
c.strMap[x] = x.Name.Table.O + "." + x.Name.Name.O
case *BetweenExpr:
c.strMap[x] = c.strMap[x.Expr] + " BETWWEN " + c.strMap[x.Left] + " AND " + c.strMap[x.Right]
default:
c.strMap[in] = fmt.Sprintf("%T", in)
}
return in, true
}

218
vendor/github.com/pingcap/tidb/bootstrap.go generated vendored Normal file
View file

@ -0,0 +1,218 @@
// Copyright 2013 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSES/QL-LICENSE file.
// 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 tidb
import (
"fmt"
"runtime/debug"
"strings"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx/variable"
)
const (
// CreateUserTable is the SQL statement creates User table in system db.
CreateUserTable = `CREATE TABLE if not exists mysql.user (
Host CHAR(64),
User CHAR(16),
Password CHAR(41),
Select_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Insert_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Update_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Delete_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Create_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Drop_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Grant_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Alter_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Show_db_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Execute_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Index_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
Create_user_priv ENUM('N','Y') NOT NULL DEFAULT 'N',
PRIMARY KEY (Host, User));`
// CreateDBPrivTable is the SQL statement creates DB scope privilege table in system db.
CreateDBPrivTable = `CREATE TABLE if not exists mysql.db (
Host CHAR(60),
DB CHAR(64),
User CHAR(16),
Select_priv ENUM('N','Y') Not Null DEFAULT 'N',
Insert_priv ENUM('N','Y') Not Null DEFAULT 'N',
Update_priv ENUM('N','Y') Not Null DEFAULT 'N',
Delete_priv ENUM('N','Y') Not Null DEFAULT 'N',
Create_priv ENUM('N','Y') Not Null DEFAULT 'N',
Drop_priv ENUM('N','Y') Not Null DEFAULT 'N',
Grant_priv ENUM('N','Y') Not Null DEFAULT 'N',
Index_priv ENUM('N','Y') Not Null DEFAULT 'N',
Alter_priv ENUM('N','Y') Not Null DEFAULT 'N',
Execute_priv ENUM('N','Y') Not Null DEFAULT 'N',
PRIMARY KEY (Host, DB, User));`
// CreateTablePrivTable is the SQL statement creates table scope privilege table in system db.
CreateTablePrivTable = `CREATE TABLE if not exists mysql.tables_priv (
Host CHAR(60),
DB CHAR(64),
User CHAR(16),
Table_name CHAR(64),
Grantor CHAR(77),
Timestamp Timestamp DEFAULT CURRENT_TIMESTAMP,
Table_priv SET('Select','Insert','Update','Delete','Create','Drop','Grant', 'Index','Alter'),
Column_priv SET('Select','Insert','Update'),
PRIMARY KEY (Host, DB, User, Table_name));`
// CreateColumnPrivTable is the SQL statement creates column scope privilege table in system db.
CreateColumnPrivTable = `CREATE TABLE if not exists mysql.columns_priv(
Host CHAR(60),
DB CHAR(64),
User CHAR(16),
Table_name CHAR(64),
Column_name CHAR(64),
Timestamp Timestamp DEFAULT CURRENT_TIMESTAMP,
Column_priv SET('Select','Insert','Update'),
PRIMARY KEY (Host, DB, User, Table_name, Column_name));`
// CreateGloablVariablesTable is the SQL statement creates global variable table in system db.
// TODO: MySQL puts GLOBAL_VARIABLES table in INFORMATION_SCHEMA db.
// INFORMATION_SCHEMA is a virtual db in TiDB. So we put this table in system db.
// Maybe we will put it back to INFORMATION_SCHEMA.
CreateGloablVariablesTable = `CREATE TABLE if not exists mysql.GLOBAL_VARIABLES(
VARIABLE_NAME VARCHAR(64) Not Null PRIMARY KEY,
VARIABLE_VALUE VARCHAR(1024) DEFAULT Null);`
// CreateTiDBTable is the SQL statement creates a table in system db.
// This table is a key-value struct contains some information used by TiDB.
// Currently we only put bootstrapped in it which indicates if the system is already bootstrapped.
CreateTiDBTable = `CREATE TABLE if not exists mysql.tidb(
VARIABLE_NAME VARCHAR(64) Not Null PRIMARY KEY,
VARIABLE_VALUE VARCHAR(1024) DEFAULT Null,
COMMENT VARCHAR(1024));`
)
// Bootstrap initiates system DB for a store.
func bootstrap(s Session) {
b, err := checkBootstrapped(s)
if err != nil {
log.Fatal(err)
}
if b {
return
}
doDDLWorks(s)
doDMLWorks(s)
}
const (
bootstrappedVar = "bootstrapped"
bootstrappedVarTrue = "True"
)
func checkBootstrapped(s Session) (bool, error) {
// Check if system db exists.
_, err := s.Execute(fmt.Sprintf("USE %s;", mysql.SystemDB))
if err != nil && infoschema.DatabaseNotExists.NotEqual(err) {
log.Fatal(err)
}
// Check bootstrapped variable value in TiDB table.
v, err := checkBootstrappedVar(s)
if err != nil {
return false, errors.Trace(err)
}
return v, nil
}
func checkBootstrappedVar(s Session) (bool, error) {
sql := fmt.Sprintf(`SELECT VARIABLE_VALUE FROM %s.%s WHERE VARIABLE_NAME="%s"`,
mysql.SystemDB, mysql.TiDBTable, bootstrappedVar)
rs, err := s.Execute(sql)
if err != nil {
if infoschema.TableNotExists.Equal(err) {
return false, nil
}
return false, errors.Trace(err)
}
if len(rs) != 1 {
return false, errors.New("Wrong number of Recordset")
}
r := rs[0]
row, err := r.Next()
if err != nil || row == nil {
return false, errors.Trace(err)
}
isBootstrapped := row.Data[0].GetString() == bootstrappedVarTrue
if isBootstrapped {
// Make sure that doesn't affect the following operations.
if err = s.FinishTxn(false); err != nil {
return false, errors.Trace(err)
}
}
return isBootstrapped, nil
}
// Execute DDL statements in bootstrap stage.
func doDDLWorks(s Session) {
// Create a test database.
mustExecute(s, "CREATE DATABASE IF NOT EXISTS test")
// Create system db.
mustExecute(s, fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s;", mysql.SystemDB))
// Create user table.
mustExecute(s, CreateUserTable)
// Create privilege tables.
mustExecute(s, CreateDBPrivTable)
mustExecute(s, CreateTablePrivTable)
mustExecute(s, CreateColumnPrivTable)
// Create global systemt variable table.
mustExecute(s, CreateGloablVariablesTable)
// Create TiDB table.
mustExecute(s, CreateTiDBTable)
}
// Execute DML statements in bootstrap stage.
// All the statements run in a single transaction.
func doDMLWorks(s Session) {
mustExecute(s, "BEGIN")
// Insert a default user with empty password.
mustExecute(s, `INSERT INTO mysql.user VALUES
("%", "root", "", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y")`)
// Init global system variables table.
values := make([]string, 0, len(variable.SysVars))
for k, v := range variable.SysVars {
value := fmt.Sprintf(`("%s", "%s")`, strings.ToLower(k), v.Value)
values = append(values, value)
}
sql := fmt.Sprintf("INSERT INTO %s.%s VALUES %s;", mysql.SystemDB, mysql.GlobalVariablesTable,
strings.Join(values, ", "))
mustExecute(s, sql)
sql = fmt.Sprintf(`INSERT INTO %s.%s VALUES("%s", "%s", "Bootstrap flag. Do not delete.")
ON DUPLICATE KEY UPDATE VARIABLE_VALUE="%s"`,
mysql.SystemDB, mysql.TiDBTable, bootstrappedVar, bootstrappedVarTrue, bootstrappedVarTrue)
mustExecute(s, sql)
mustExecute(s, "COMMIT")
}
func mustExecute(s Session, sql string) {
_, err := s.Execute(sql)
if err != nil {
debug.PrintStack()
log.Fatal(err)
}
}

232
vendor/github.com/pingcap/tidb/column/column.go generated vendored Normal file
View file

@ -0,0 +1,232 @@
// Copyright 2013 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSES/QL-LICENSE file.
// 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 column
import (
"strings"
"github.com/juju/errors"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/util/types"
)
// Col provides meta data describing a table column.
type Col struct {
model.ColumnInfo
}
// PrimaryKeyName defines primary key name.
const PrimaryKeyName = "PRIMARY"
// IndexedCol defines an index with info.
type IndexedCol struct {
model.IndexInfo
X kv.Index
}
// String implements fmt.Stringer interface.
func (c *Col) String() string {
ans := []string{c.Name.O, types.TypeToStr(c.Tp, c.Charset)}
if mysql.HasAutoIncrementFlag(c.Flag) {
ans = append(ans, "AUTO_INCREMENT")
}
if mysql.HasNotNullFlag(c.Flag) {
ans = append(ans, "NOT NULL")
}
return strings.Join(ans, " ")
}
// FindCol finds column in cols by name.
func FindCol(cols []*Col, name string) *Col {
for _, col := range cols {
if strings.EqualFold(col.Name.O, name) {
return col
}
}
return nil
}
// FindCols finds columns in cols by names.
func FindCols(cols []*Col, names []string) ([]*Col, error) {
var rcols []*Col
for _, name := range names {
col := FindCol(cols, name)
if col != nil {
rcols = append(rcols, col)
} else {
return nil, errors.Errorf("unknown column %s", name)
}
}
return rcols, nil
}
// FindOnUpdateCols finds columns which have OnUpdateNow flag.
func FindOnUpdateCols(cols []*Col) []*Col {
var rcols []*Col
for _, col := range cols {
if mysql.HasOnUpdateNowFlag(col.Flag) {
rcols = append(rcols, col)
}
}
return rcols
}
// CastValues casts values based on columns type.
func CastValues(ctx context.Context, rec []types.Datum, cols []*Col) (err error) {
for _, c := range cols {
var converted types.Datum
converted, err = rec[c.Offset].ConvertTo(&c.FieldType)
if err != nil {
return errors.Trace(err)
}
rec[c.Offset] = converted
}
return nil
}
// ColDesc describes column information like MySQL desc and show columns do.
type ColDesc struct {
Field string
Type string
Collation string
Null string
Key string
DefaultValue interface{}
Extra string
Privileges string
Comment string
}
const defaultPrivileges string = "select,insert,update,references"
// GetTypeDesc gets the description for column type.
func (c *Col) GetTypeDesc() string {
desc := c.FieldType.CompactStr()
if mysql.HasUnsignedFlag(c.Flag) {
desc += " UNSIGNED"
}
return desc
}
// NewColDesc returns a new ColDesc for a column.
func NewColDesc(col *Col) *ColDesc {
// TODO: if we have no primary key and a unique index which's columns are all not null
// we will set these columns' flag as PriKeyFlag
// see https://dev.mysql.com/doc/refman/5.7/en/show-columns.html
// create table
name := col.Name
nullFlag := "YES"
if mysql.HasNotNullFlag(col.Flag) {
nullFlag = "NO"
}
keyFlag := ""
if mysql.HasPriKeyFlag(col.Flag) {
keyFlag = "PRI"
} else if mysql.HasUniKeyFlag(col.Flag) {
keyFlag = "UNI"
} else if mysql.HasMultipleKeyFlag(col.Flag) {
keyFlag = "MUL"
}
var defaultValue interface{}
if !mysql.HasNoDefaultValueFlag(col.Flag) {
defaultValue = col.DefaultValue
}
extra := ""
if mysql.HasAutoIncrementFlag(col.Flag) {
extra = "auto_increment"
} else if mysql.HasOnUpdateNowFlag(col.Flag) {
extra = "on update CURRENT_TIMESTAMP"
}
return &ColDesc{
Field: name.O,
Type: col.GetTypeDesc(),
Collation: col.Collate,
Null: nullFlag,
Key: keyFlag,
DefaultValue: defaultValue,
Extra: extra,
Privileges: defaultPrivileges,
Comment: "",
}
}
// ColDescFieldNames returns the fields name in result set for desc and show columns.
func ColDescFieldNames(full bool) []string {
if full {
return []string{"Field", "Type", "Collation", "Null", "Key", "Default", "Extra", "Privileges", "Comment"}
}
return []string{"Field", "Type", "Null", "Key", "Default", "Extra"}
}
// CheckOnce checks if there are duplicated column names in cols.
func CheckOnce(cols []*Col) error {
m := map[string]struct{}{}
for _, col := range cols {
name := col.Name
_, ok := m[name.L]
if ok {
return errors.Errorf("column specified twice - %s", name)
}
m[name.L] = struct{}{}
}
return nil
}
// CheckNotNull checks if nil value set to a column with NotNull flag is set.
func (c *Col) CheckNotNull(data types.Datum) error {
if mysql.HasNotNullFlag(c.Flag) && data.Kind() == types.KindNull {
return errors.Errorf("Column %s can't be null.", c.Name)
}
return nil
}
// IsPKHandleColumn checks if the column is primary key handle column.
func (c *Col) IsPKHandleColumn(tbInfo *model.TableInfo) bool {
return mysql.HasPriKeyFlag(c.Flag) && tbInfo.PKIsHandle
}
// CheckNotNull checks if row has nil value set to a column with NotNull flag set.
func CheckNotNull(cols []*Col, row []types.Datum) error {
for _, c := range cols {
if err := c.CheckNotNull(row[c.Offset]); err != nil {
return errors.Trace(err)
}
}
return nil
}
// FetchValues fetches indexed values from a row.
func (idx *IndexedCol) FetchValues(r []types.Datum) ([]types.Datum, error) {
vals := make([]types.Datum, len(idx.Columns))
for i, ic := range idx.Columns {
if ic.Offset < 0 || ic.Offset > len(r) {
return nil, errors.New("Index column offset out of bound")
}
vals[i] = r[ic.Offset]
}
return vals, nil
}

38
vendor/github.com/pingcap/tidb/context/context.go generated vendored Normal file
View file

@ -0,0 +1,38 @@
// 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 context
import (
"fmt"
"github.com/pingcap/tidb/kv"
)
// Context is an interface for transaction and executive args environment.
type Context interface {
// GetTxn gets a transaction for futher execution.
GetTxn(forceNew bool) (kv.Transaction, error)
// FinishTxn commits or rolls back the current transaction.
FinishTxn(rollback bool) error
// SetValue saves a value associated with this context for key.
SetValue(key fmt.Stringer, value interface{})
// Value returns the value associated with this context for key.
Value(key fmt.Stringer) interface{}
// ClearValue clears the value associated with this context for key.
ClearValue(key fmt.Stringer)
}

178
vendor/github.com/pingcap/tidb/ddl/bg_worker.go generated vendored Normal file
View file

@ -0,0 +1,178 @@
// 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 ddl
import (
"time"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/terror"
)
// handleBgJobQueue handles the background job queue.
func (d *ddl) handleBgJobQueue() error {
if d.isClosed() {
return nil
}
job := &model.Job{}
err := kv.RunInNewTxn(d.store, false, func(txn kv.Transaction) error {
t := meta.NewMeta(txn)
owner, err := d.checkOwner(t, bgJobFlag)
if terror.ErrorEqual(err, ErrNotOwner) {
return nil
}
if err != nil {
return errors.Trace(err)
}
// get the first background job and run
job, err = d.getFirstBgJob(t)
if err != nil {
return errors.Trace(err)
}
if job == nil {
return nil
}
d.runBgJob(t, job)
if job.IsFinished() {
err = d.finishBgJob(t, job)
} else {
err = d.updateBgJob(t, job)
}
if err != nil {
return errors.Trace(err)
}
owner.LastUpdateTS = time.Now().UnixNano()
err = t.SetBgJobOwner(owner)
return errors.Trace(err)
})
if err != nil {
return errors.Trace(err)
}
return nil
}
// runBgJob runs a background job.
func (d *ddl) runBgJob(t *meta.Meta, job *model.Job) {
job.State = model.JobRunning
var err error
switch job.Type {
case model.ActionDropSchema:
err = d.delReorgSchema(t, job)
case model.ActionDropTable:
err = d.delReorgTable(t, job)
default:
job.State = model.JobCancelled
err = errors.Errorf("invalid background job %v", job)
}
if err != nil {
if job.State != model.JobCancelled {
log.Errorf("run background job err %v", errors.ErrorStack(err))
}
job.Error = err.Error()
job.ErrorCount++
}
}
// prepareBgJob prepares a background job.
func (d *ddl) prepareBgJob(ddlJob *model.Job) error {
job := &model.Job{
ID: ddlJob.ID,
SchemaID: ddlJob.SchemaID,
TableID: ddlJob.TableID,
Type: ddlJob.Type,
Args: ddlJob.Args,
}
err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
t := meta.NewMeta(txn)
err1 := t.EnQueueBgJob(job)
return errors.Trace(err1)
})
return errors.Trace(err)
}
// startBgJob starts a background job.
func (d *ddl) startBgJob(tp model.ActionType) {
switch tp {
case model.ActionDropSchema, model.ActionDropTable:
asyncNotify(d.bgJobCh)
}
}
// getFirstBgJob gets the first background job.
func (d *ddl) getFirstBgJob(t *meta.Meta) (*model.Job, error) {
job, err := t.GetBgJob(0)
return job, errors.Trace(err)
}
// updateBgJob updates a background job.
func (d *ddl) updateBgJob(t *meta.Meta, job *model.Job) error {
err := t.UpdateBgJob(0, job)
return errors.Trace(err)
}
// finishBgJob finishs a background job.
func (d *ddl) finishBgJob(t *meta.Meta, job *model.Job) error {
log.Warnf("[ddl] finish background job %v", job)
if _, err := t.DeQueueBgJob(); err != nil {
return errors.Trace(err)
}
err := t.AddHistoryBgJob(job)
return errors.Trace(err)
}
func (d *ddl) onBackgroundWorker() {
defer d.wait.Done()
// we use 4 * lease time to check owner's timeout, so here, we will update owner's status
// every 2 * lease time, if lease is 0, we will use default 10s.
checkTime := chooseLeaseTime(2*d.lease, 10*time.Second)
ticker := time.NewTicker(checkTime)
defer ticker.Stop()
for {
select {
case <-ticker.C:
log.Debugf("[ddl] wait %s to check background job status again", checkTime)
case <-d.bgJobCh:
case <-d.quitCh:
return
}
err := d.handleBgJobQueue()
if err != nil {
log.Errorf("[ddl] handle background job err %v", errors.ErrorStack(err))
}
}
}

45
vendor/github.com/pingcap/tidb/ddl/callback.go generated vendored Normal file
View file

@ -0,0 +1,45 @@
// 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 ddl
import "github.com/pingcap/tidb/model"
// Callback is the interface supporting callback function when DDL changed.
type Callback interface {
// OnChanged is called after schema is changed.
OnChanged(err error) error
// OnJobRunBefore is called before running job.
OnJobRunBefore(job *model.Job)
// OnJobUpdated is called after the running job is updated.
OnJobUpdated(job *model.Job)
}
// BaseCallback implements Callback.OnChanged interface.
type BaseCallback struct {
}
// OnChanged implements Callback interface.
func (c *BaseCallback) OnChanged(err error) error {
return err
}
// OnJobRunBefore implements Callback.OnJobRunBefore interface.
func (c *BaseCallback) OnJobRunBefore(job *model.Job) {
// Nothing to do.
}
// OnJobUpdated implements Callback.OnJobUpdated interface.
func (c *BaseCallback) OnJobUpdated(job *model.Job) {
// Nothing to do.
}

430
vendor/github.com/pingcap/tidb/ddl/column.go generated vendored Normal file
View file

@ -0,0 +1,430 @@
// 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 ddl
import (
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/column"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/table/tables"
"github.com/pingcap/tidb/terror"
)
func (d *ddl) adjustColumnOffset(columns []*model.ColumnInfo, indices []*model.IndexInfo, offset int, added bool) {
offsetChanged := make(map[int]int)
if added {
for i := offset + 1; i < len(columns); i++ {
offsetChanged[columns[i].Offset] = i
columns[i].Offset = i
}
columns[offset].Offset = offset
} else {
for i := offset + 1; i < len(columns); i++ {
offsetChanged[columns[i].Offset] = i - 1
columns[i].Offset = i - 1
}
columns[offset].Offset = len(columns) - 1
}
// TODO: index can't cover the add/remove column with offset now, we may check this later.
// Update index column offset info.
for _, idx := range indices {
for _, col := range idx.Columns {
newOffset, ok := offsetChanged[col.Offset]
if ok {
col.Offset = newOffset
}
}
}
}
func (d *ddl) addColumn(tblInfo *model.TableInfo, colInfo *model.ColumnInfo, pos *ast.ColumnPosition) (*model.ColumnInfo, int, error) {
// Check column name duplicate.
cols := tblInfo.Columns
position := len(cols)
// Get column position.
if pos.Tp == ast.ColumnPositionFirst {
position = 0
} else if pos.Tp == ast.ColumnPositionAfter {
c := findCol(cols, pos.RelativeColumn.Name.L)
if c == nil {
return nil, 0, errors.Errorf("No such column: %v", pos.RelativeColumn)
}
// Insert position is after the mentioned column.
position = c.Offset + 1
}
colInfo.State = model.StateNone
// To support add column asynchronous, we should mark its offset as the last column.
// So that we can use origin column offset to get value from row.
colInfo.Offset = len(cols)
// Insert col into the right place of the column list.
newCols := make([]*model.ColumnInfo, 0, len(cols)+1)
newCols = append(newCols, cols[:position]...)
newCols = append(newCols, colInfo)
newCols = append(newCols, cols[position:]...)
tblInfo.Columns = newCols
return colInfo, position, nil
}
func (d *ddl) onAddColumn(t *meta.Meta, job *model.Job) error {
schemaID := job.SchemaID
tblInfo, err := d.getTableInfo(t, job)
if err != nil {
return errors.Trace(err)
}
col := &model.ColumnInfo{}
pos := &ast.ColumnPosition{}
offset := 0
err = job.DecodeArgs(col, pos, &offset)
if err != nil {
job.State = model.JobCancelled
return errors.Trace(err)
}
columnInfo := findCol(tblInfo.Columns, col.Name.L)
if columnInfo != nil {
if columnInfo.State == model.StatePublic {
// we already have a column with same column name
job.State = model.JobCancelled
return errors.Errorf("ADD COLUMN: column already exist %s", col.Name.L)
}
} else {
columnInfo, offset, err = d.addColumn(tblInfo, col, pos)
if err != nil {
job.State = model.JobCancelled
return errors.Trace(err)
}
// Set offset arg to job.
if offset != 0 {
job.Args = []interface{}{columnInfo, pos, offset}
}
}
_, err = t.GenSchemaVersion()
if err != nil {
return errors.Trace(err)
}
switch columnInfo.State {
case model.StateNone:
// none -> delete only
job.SchemaState = model.StateDeleteOnly
columnInfo.State = model.StateDeleteOnly
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateDeleteOnly:
// delete only -> write only
job.SchemaState = model.StateWriteOnly
columnInfo.State = model.StateWriteOnly
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateWriteOnly:
// write only -> reorganization
job.SchemaState = model.StateWriteReorganization
columnInfo.State = model.StateWriteReorganization
// initialize SnapshotVer to 0 for later reorganization check.
job.SnapshotVer = 0
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateWriteReorganization:
// reorganization -> public
// get the current version for reorganization if we don't have
reorgInfo, err := d.getReorgInfo(t, job)
if err != nil || reorgInfo.first {
// if we run reorg firstly, we should update the job snapshot version
// and then run the reorg next time.
return errors.Trace(err)
}
tbl, err := d.getTable(schemaID, tblInfo)
if err != nil {
return errors.Trace(err)
}
err = d.runReorgJob(func() error {
return d.backfillColumn(tbl, columnInfo, reorgInfo)
})
if terror.ErrorEqual(err, errWaitReorgTimeout) {
// if timeout, we should return, check for the owner and re-wait job done.
return nil
}
if err != nil {
return errors.Trace(err)
}
// Adjust column offset.
d.adjustColumnOffset(tblInfo.Columns, tblInfo.Indices, offset, true)
columnInfo.State = model.StatePublic
if err = t.UpdateTable(schemaID, tblInfo); err != nil {
return errors.Trace(err)
}
// finish this job
job.SchemaState = model.StatePublic
job.State = model.JobDone
return nil
default:
return errors.Errorf("invalid column state %v", columnInfo.State)
}
}
func (d *ddl) onDropColumn(t *meta.Meta, job *model.Job) error {
schemaID := job.SchemaID
tblInfo, err := d.getTableInfo(t, job)
if err != nil {
return errors.Trace(err)
}
var colName model.CIStr
err = job.DecodeArgs(&colName)
if err != nil {
job.State = model.JobCancelled
return errors.Trace(err)
}
colInfo := findCol(tblInfo.Columns, colName.L)
if colInfo == nil {
job.State = model.JobCancelled
return errors.Errorf("column %s doesn't exist", colName)
}
if len(tblInfo.Columns) == 1 {
job.State = model.JobCancelled
return errors.Errorf("can't drop only column %s in table %s", colName, tblInfo.Name)
}
// we don't support drop column with index covered now.
// we must drop the index first, then drop the column.
for _, indexInfo := range tblInfo.Indices {
for _, col := range indexInfo.Columns {
if col.Name.L == colName.L {
job.State = model.JobCancelled
return errors.Errorf("can't drop column %s with index %s covered now", colName, indexInfo.Name)
}
}
}
_, err = t.GenSchemaVersion()
if err != nil {
return errors.Trace(err)
}
switch colInfo.State {
case model.StatePublic:
// public -> write only
job.SchemaState = model.StateWriteOnly
colInfo.State = model.StateWriteOnly
// set this column's offset to the last and reset all following columns' offset
d.adjustColumnOffset(tblInfo.Columns, tblInfo.Indices, colInfo.Offset, false)
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateWriteOnly:
// write only -> delete only
job.SchemaState = model.StateDeleteOnly
colInfo.State = model.StateDeleteOnly
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateDeleteOnly:
// delete only -> reorganization
job.SchemaState = model.StateDeleteReorganization
colInfo.State = model.StateDeleteReorganization
// initialize SnapshotVer to 0 for later reorganization check.
job.SnapshotVer = 0
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateDeleteReorganization:
// reorganization -> absent
reorgInfo, err := d.getReorgInfo(t, job)
if err != nil || reorgInfo.first {
// if we run reorg firstly, we should update the job snapshot version
// and then run the reorg next time.
return errors.Trace(err)
}
tbl, err := d.getTable(schemaID, tblInfo)
if err != nil {
return errors.Trace(err)
}
err = d.runReorgJob(func() error {
return d.dropTableColumn(tbl, colInfo, reorgInfo)
})
if terror.ErrorEqual(err, errWaitReorgTimeout) {
// if timeout, we should return, check for the owner and re-wait job done.
return nil
}
if err != nil {
return errors.Trace(err)
}
// all reorganization jobs done, drop this column
newColumns := make([]*model.ColumnInfo, 0, len(tblInfo.Columns))
for _, col := range tblInfo.Columns {
if col.Name.L != colName.L {
newColumns = append(newColumns, col)
}
}
tblInfo.Columns = newColumns
if err = t.UpdateTable(schemaID, tblInfo); err != nil {
return errors.Trace(err)
}
// finish this job
job.SchemaState = model.StateNone
job.State = model.JobDone
return nil
default:
return errors.Errorf("invalid table state %v", tblInfo.State)
}
}
// How to backfill column data in reorganization state?
// 1. Generate a snapshot with special version.
// 2. Traverse the snapshot, get every row in the table.
// 3. For one row, if the row has been already deleted, skip to next row.
// 4. If not deleted, check whether column data has existed, if existed, skip to next row.
// 5. If column data doesn't exist, backfill the column with default value and then continue to handle next row.
func (d *ddl) backfillColumn(t table.Table, columnInfo *model.ColumnInfo, reorgInfo *reorgInfo) error {
seekHandle := reorgInfo.Handle
version := reorgInfo.SnapshotVer
for {
handles, err := d.getSnapshotRows(t, version, seekHandle)
if err != nil {
return errors.Trace(err)
} else if len(handles) == 0 {
return nil
}
seekHandle = handles[len(handles)-1] + 1
err = d.backfillColumnData(t, columnInfo, handles, reorgInfo)
if err != nil {
return errors.Trace(err)
}
}
}
func (d *ddl) backfillColumnData(t table.Table, columnInfo *model.ColumnInfo, handles []int64, reorgInfo *reorgInfo) error {
for _, handle := range handles {
log.Info("[ddl] backfill column...", handle)
err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
if err := d.isReorgRunnable(txn); err != nil {
return errors.Trace(err)
}
// First check if row exists.
exist, err := checkRowExist(txn, t, handle)
if err != nil {
return errors.Trace(err)
} else if !exist {
// If row doesn't exist, skip it.
return nil
}
backfillKey := t.RecordKey(handle, &column.Col{ColumnInfo: *columnInfo})
backfillValue, err := txn.Get(backfillKey)
if err != nil && !kv.IsErrNotFound(err) {
return errors.Trace(err)
}
if backfillValue != nil {
return nil
}
value, _, err := table.GetColDefaultValue(nil, columnInfo)
if err != nil {
return errors.Trace(err)
}
// must convert to the column field type.
v, err := value.ConvertTo(&columnInfo.FieldType)
if err != nil {
return errors.Trace(err)
}
err = lockRow(txn, t, handle)
if err != nil {
return errors.Trace(err)
}
err = tables.SetColValue(txn, backfillKey, v)
if err != nil {
return errors.Trace(err)
}
return errors.Trace(reorgInfo.UpdateHandle(txn, handle))
})
if err != nil {
return errors.Trace(err)
}
}
return nil
}
func (d *ddl) dropTableColumn(t table.Table, colInfo *model.ColumnInfo, reorgInfo *reorgInfo) error {
version := reorgInfo.SnapshotVer
seekHandle := reorgInfo.Handle
col := &column.Col{ColumnInfo: *colInfo}
for {
handles, err := d.getSnapshotRows(t, version, seekHandle)
if err != nil {
return errors.Trace(err)
} else if len(handles) == 0 {
return nil
}
seekHandle = handles[len(handles)-1] + 1
err = kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
if err1 := d.isReorgRunnable(txn); err1 != nil {
return errors.Trace(err1)
}
var h int64
for _, h = range handles {
key := t.RecordKey(h, col)
err1 := txn.Delete(key)
if err1 != nil && !terror.ErrorEqual(err1, kv.ErrNotExist) {
return errors.Trace(err1)
}
}
return errors.Trace(reorgInfo.UpdateHandle(txn, h))
})
if err != nil {
return errors.Trace(err)
}
}
}

978
vendor/github.com/pingcap/tidb/ddl/ddl.go generated vendored Normal file
View file

@ -0,0 +1,978 @@
// Copyright 2013 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSES/QL-LICENSE file.
// 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 ddl
import (
"fmt"
"strings"
"sync"
"time"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/column"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/evaluator"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/meta/autoid"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/util/charset"
"github.com/pingcap/tidb/util/types"
"github.com/twinj/uuid"
)
// DDL is responsible for updating schema in data store and maintaining in-memory InfoSchema cache.
type DDL interface {
CreateSchema(ctx context.Context, name model.CIStr, charsetInfo *ast.CharsetOpt) error
DropSchema(ctx context.Context, schema model.CIStr) error
CreateTable(ctx context.Context, ident ast.Ident, cols []*ast.ColumnDef,
constrs []*ast.Constraint, options []*ast.TableOption) error
DropTable(ctx context.Context, tableIdent ast.Ident) (err error)
CreateIndex(ctx context.Context, tableIdent ast.Ident, unique bool, indexName model.CIStr,
columnNames []*ast.IndexColName) error
DropIndex(ctx context.Context, tableIdent ast.Ident, indexName model.CIStr) error
GetInformationSchema() infoschema.InfoSchema
AlterTable(ctx context.Context, tableIdent ast.Ident, spec []*ast.AlterTableSpec) error
// SetLease will reset the lease time for online DDL change,
// it's a very dangerous function and you must guarantee that all servers have the same lease time.
SetLease(lease time.Duration)
// GetLease returns current schema lease time.
GetLease() time.Duration
// Stats returns the DDL statistics.
Stats() (map[string]interface{}, error)
// GetScope gets the status variables scope.
GetScope(status string) variable.ScopeFlag
// Stop stops DDL worker.
Stop() error
// Start starts DDL worker.
Start() error
}
type ddl struct {
m sync.RWMutex
infoHandle *infoschema.Handle
hook Callback
store kv.Storage
// schema lease seconds.
lease time.Duration
uuid string
ddlJobCh chan struct{}
ddlJobDoneCh chan struct{}
// drop database/table job runs in the background.
bgJobCh chan struct{}
// reorgDoneCh is for reorganization, if the reorganization job is done,
// we will use this channel to notify outer.
// TODO: now we use goroutine to simulate reorganization jobs, later we may
// use a persistent job list.
reorgDoneCh chan error
quitCh chan struct{}
wait sync.WaitGroup
}
// NewDDL creates a new DDL.
func NewDDL(store kv.Storage, infoHandle *infoschema.Handle, hook Callback, lease time.Duration) DDL {
return newDDL(store, infoHandle, hook, lease)
}
func newDDL(store kv.Storage, infoHandle *infoschema.Handle, hook Callback, lease time.Duration) *ddl {
if hook == nil {
hook = &BaseCallback{}
}
d := &ddl{
infoHandle: infoHandle,
hook: hook,
store: store,
lease: lease,
uuid: uuid.NewV4().String(),
ddlJobCh: make(chan struct{}, 1),
ddlJobDoneCh: make(chan struct{}, 1),
bgJobCh: make(chan struct{}, 1),
}
d.start()
variable.RegisterStatistics(d)
return d
}
func (d *ddl) Stop() error {
d.m.Lock()
defer d.m.Unlock()
d.close()
err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
t := meta.NewMeta(txn)
owner, err1 := t.GetDDLJobOwner()
if err1 != nil {
return errors.Trace(err1)
}
if owner == nil || owner.OwnerID != d.uuid {
return nil
}
// ddl job's owner is me, clean it so other servers can compete for it quickly.
return t.SetDDLJobOwner(&model.Owner{})
})
if err != nil {
return errors.Trace(err)
}
err = kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
t := meta.NewMeta(txn)
owner, err1 := t.GetBgJobOwner()
if err1 != nil {
return errors.Trace(err1)
}
if owner == nil || owner.OwnerID != d.uuid {
return nil
}
// background job's owner is me, clean it so other servers can compete for it quickly.
return t.SetBgJobOwner(&model.Owner{})
})
return errors.Trace(err)
}
func (d *ddl) Start() error {
d.m.Lock()
defer d.m.Unlock()
if !d.isClosed() {
return nil
}
d.start()
return nil
}
func (d *ddl) start() {
d.quitCh = make(chan struct{})
d.wait.Add(2)
go d.onBackgroundWorker()
go d.onDDLWorker()
// for every start, we will send a fake job to let worker
// check owner first and try to find whether a job exists and run.
asyncNotify(d.ddlJobCh)
asyncNotify(d.bgJobCh)
}
func (d *ddl) close() {
if d.isClosed() {
return
}
close(d.quitCh)
d.wait.Wait()
}
func (d *ddl) isClosed() bool {
select {
case <-d.quitCh:
return true
default:
return false
}
}
func (d *ddl) SetLease(lease time.Duration) {
d.m.Lock()
defer d.m.Unlock()
if lease == d.lease {
return
}
log.Warnf("[ddl] change schema lease %s -> %s", d.lease, lease)
if d.isClosed() {
// if already closed, just set lease and return
d.lease = lease
return
}
// close the running worker and start again
d.close()
d.lease = lease
d.start()
}
func (d *ddl) GetLease() time.Duration {
d.m.RLock()
lease := d.lease
d.m.RUnlock()
return lease
}
func (d *ddl) GetInformationSchema() infoschema.InfoSchema {
return d.infoHandle.Get()
}
func (d *ddl) genGlobalID() (int64, error) {
var globalID int64
err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
var err error
globalID, err = meta.NewMeta(txn).GenGlobalID()
return errors.Trace(err)
})
return globalID, errors.Trace(err)
}
func (d *ddl) CreateSchema(ctx context.Context, schema model.CIStr, charsetInfo *ast.CharsetOpt) (err error) {
is := d.GetInformationSchema()
_, ok := is.SchemaByName(schema)
if ok {
return errors.Trace(infoschema.DatabaseExists)
}
schemaID, err := d.genGlobalID()
if err != nil {
return errors.Trace(err)
}
dbInfo := &model.DBInfo{
Name: schema,
}
if charsetInfo != nil {
dbInfo.Charset = charsetInfo.Chs
dbInfo.Collate = charsetInfo.Col
} else {
dbInfo.Charset, dbInfo.Collate = getDefaultCharsetAndCollate()
}
job := &model.Job{
SchemaID: schemaID,
Type: model.ActionCreateSchema,
Args: []interface{}{dbInfo},
}
err = d.startDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
func (d *ddl) DropSchema(ctx context.Context, schema model.CIStr) (err error) {
is := d.GetInformationSchema()
old, ok := is.SchemaByName(schema)
if !ok {
return errors.Trace(infoschema.DatabaseNotExists)
}
job := &model.Job{
SchemaID: old.ID,
Type: model.ActionDropSchema,
}
err = d.startDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
func getDefaultCharsetAndCollate() (string, string) {
// TODO: TableDefaultCharset-->DatabaseDefaultCharset-->SystemDefaultCharset.
// TODO: change TableOption parser to parse collate.
// This is a tmp solution.
return "utf8", "utf8_unicode_ci"
}
func setColumnFlagWithConstraint(colMap map[string]*column.Col, v *ast.Constraint) {
switch v.Tp {
case ast.ConstraintPrimaryKey:
for _, key := range v.Keys {
c, ok := colMap[key.Column.Name.L]
if !ok {
// TODO: table constraint on unknown column.
continue
}
c.Flag |= mysql.PriKeyFlag
// Primary key can not be NULL.
c.Flag |= mysql.NotNullFlag
}
case ast.ConstraintUniq, ast.ConstraintUniqIndex, ast.ConstraintUniqKey:
for i, key := range v.Keys {
c, ok := colMap[key.Column.Name.L]
if !ok {
// TODO: table constraint on unknown column.
continue
}
if i == 0 {
// Only the first column can be set
// if unique index has multi columns,
// the flag should be MultipleKeyFlag.
// See: https://dev.mysql.com/doc/refman/5.7/en/show-columns.html
if len(v.Keys) > 1 {
c.Flag |= mysql.MultipleKeyFlag
} else {
c.Flag |= mysql.UniqueKeyFlag
}
}
}
case ast.ConstraintKey, ast.ConstraintIndex:
for i, key := range v.Keys {
c, ok := colMap[key.Column.Name.L]
if !ok {
// TODO: table constraint on unknown column.
continue
}
if i == 0 {
// Only the first column can be set.
c.Flag |= mysql.MultipleKeyFlag
}
}
}
}
func (d *ddl) buildColumnsAndConstraints(ctx context.Context, colDefs []*ast.ColumnDef,
constraints []*ast.Constraint) ([]*column.Col, []*ast.Constraint, error) {
var cols []*column.Col
colMap := map[string]*column.Col{}
for i, colDef := range colDefs {
col, cts, err := d.buildColumnAndConstraint(ctx, i, colDef)
if err != nil {
return nil, nil, errors.Trace(err)
}
col.State = model.StatePublic
constraints = append(constraints, cts...)
cols = append(cols, col)
colMap[colDef.Name.Name.L] = col
}
// traverse table Constraints and set col.flag
for _, v := range constraints {
setColumnFlagWithConstraint(colMap, v)
}
return cols, constraints, nil
}
func (d *ddl) buildColumnAndConstraint(ctx context.Context, offset int,
colDef *ast.ColumnDef) (*column.Col, []*ast.Constraint, error) {
// Set charset.
if len(colDef.Tp.Charset) == 0 {
switch colDef.Tp.Tp {
case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeBlob, mysql.TypeTinyBlob, mysql.TypeMediumBlob, mysql.TypeLongBlob:
colDef.Tp.Charset, colDef.Tp.Collate = getDefaultCharsetAndCollate()
default:
colDef.Tp.Charset = charset.CharsetBin
colDef.Tp.Collate = charset.CharsetBin
}
}
col, cts, err := columnDefToCol(ctx, offset, colDef)
if err != nil {
return nil, nil, errors.Trace(err)
}
col.ID, err = d.genGlobalID()
if err != nil {
return nil, nil, errors.Trace(err)
}
return col, cts, nil
}
// columnDefToCol converts ColumnDef to Col and TableConstraints.
func columnDefToCol(ctx context.Context, offset int, colDef *ast.ColumnDef) (*column.Col, []*ast.Constraint, error) {
constraints := []*ast.Constraint{}
col := &column.Col{
ColumnInfo: model.ColumnInfo{
Offset: offset,
Name: colDef.Name.Name,
FieldType: *colDef.Tp,
},
}
// Check and set TimestampFlag and OnUpdateNowFlag.
if col.Tp == mysql.TypeTimestamp {
col.Flag |= mysql.TimestampFlag
col.Flag |= mysql.OnUpdateNowFlag
col.Flag |= mysql.NotNullFlag
}
// If flen is not assigned, assigned it by type.
if col.Flen == types.UnspecifiedLength {
col.Flen = mysql.GetDefaultFieldLength(col.Tp)
}
if col.Decimal == types.UnspecifiedLength {
col.Decimal = mysql.GetDefaultDecimal(col.Tp)
}
setOnUpdateNow := false
hasDefaultValue := false
if colDef.Options != nil {
keys := []*ast.IndexColName{
{
Column: colDef.Name,
Length: colDef.Tp.Flen,
},
}
for _, v := range colDef.Options {
switch v.Tp {
case ast.ColumnOptionNotNull:
col.Flag |= mysql.NotNullFlag
case ast.ColumnOptionNull:
col.Flag &= ^uint(mysql.NotNullFlag)
removeOnUpdateNowFlag(col)
case ast.ColumnOptionAutoIncrement:
col.Flag |= mysql.AutoIncrementFlag
case ast.ColumnOptionPrimaryKey:
constraint := &ast.Constraint{Tp: ast.ConstraintPrimaryKey, Keys: keys}
constraints = append(constraints, constraint)
col.Flag |= mysql.PriKeyFlag
case ast.ColumnOptionUniq:
constraint := &ast.Constraint{Tp: ast.ConstraintUniq, Name: colDef.Name.Name.O, Keys: keys}
constraints = append(constraints, constraint)
col.Flag |= mysql.UniqueKeyFlag
case ast.ColumnOptionIndex:
constraint := &ast.Constraint{Tp: ast.ConstraintIndex, Name: colDef.Name.Name.O, Keys: keys}
constraints = append(constraints, constraint)
case ast.ColumnOptionUniqIndex:
constraint := &ast.Constraint{Tp: ast.ConstraintUniqIndex, Name: colDef.Name.Name.O, Keys: keys}
constraints = append(constraints, constraint)
col.Flag |= mysql.UniqueKeyFlag
case ast.ColumnOptionKey:
constraint := &ast.Constraint{Tp: ast.ConstraintKey, Name: colDef.Name.Name.O, Keys: keys}
constraints = append(constraints, constraint)
case ast.ColumnOptionUniqKey:
constraint := &ast.Constraint{Tp: ast.ConstraintUniqKey, Name: colDef.Name.Name.O, Keys: keys}
constraints = append(constraints, constraint)
col.Flag |= mysql.UniqueKeyFlag
case ast.ColumnOptionDefaultValue:
value, err := getDefaultValue(ctx, v, colDef.Tp.Tp, colDef.Tp.Decimal)
if err != nil {
return nil, nil, errors.Errorf("invalid default value - %s", errors.Trace(err))
}
col.DefaultValue = value
hasDefaultValue = true
removeOnUpdateNowFlag(col)
case ast.ColumnOptionOnUpdate:
if !evaluator.IsCurrentTimeExpr(v.Expr) {
return nil, nil, errors.Errorf("invalid ON UPDATE for - %s", col.Name)
}
col.Flag |= mysql.OnUpdateNowFlag
setOnUpdateNow = true
case ast.ColumnOptionFulltext, ast.ColumnOptionComment:
// Do nothing.
}
}
}
setTimestampDefaultValue(col, hasDefaultValue, setOnUpdateNow)
// Set `NoDefaultValueFlag` if this field doesn't have a default value and
// it is `not null` and not an `AUTO_INCREMENT` field or `TIMESTAMP` field.
setNoDefaultValueFlag(col, hasDefaultValue)
err := checkDefaultValue(col, hasDefaultValue)
if err != nil {
return nil, nil, errors.Trace(err)
}
if col.Charset == charset.CharsetBin {
col.Flag |= mysql.BinaryFlag
}
return col, constraints, nil
}
func getDefaultValue(ctx context.Context, c *ast.ColumnOption, tp byte, fsp int) (interface{}, error) {
if tp == mysql.TypeTimestamp || tp == mysql.TypeDatetime {
value, err := evaluator.GetTimeValue(ctx, c.Expr, tp, fsp)
if err != nil {
return nil, errors.Trace(err)
}
// Value is nil means `default null`.
if value == nil {
return nil, nil
}
// If value is mysql.Time, convert it to string.
if vv, ok := value.(mysql.Time); ok {
return vv.String(), nil
}
return value, nil
}
v, err := evaluator.Eval(ctx, c.Expr)
if err != nil {
return nil, errors.Trace(err)
}
return v, nil
}
func removeOnUpdateNowFlag(c *column.Col) {
// For timestamp Col, if it is set null or default value,
// OnUpdateNowFlag should be removed.
if mysql.HasTimestampFlag(c.Flag) {
c.Flag &= ^uint(mysql.OnUpdateNowFlag)
}
}
func setTimestampDefaultValue(c *column.Col, hasDefaultValue bool, setOnUpdateNow bool) {
if hasDefaultValue {
return
}
// For timestamp Col, if is not set default value or not set null, use current timestamp.
if mysql.HasTimestampFlag(c.Flag) && mysql.HasNotNullFlag(c.Flag) {
if setOnUpdateNow {
c.DefaultValue = evaluator.ZeroTimestamp
} else {
c.DefaultValue = evaluator.CurrentTimestamp
}
}
}
func setNoDefaultValueFlag(c *column.Col, hasDefaultValue bool) {
if hasDefaultValue {
return
}
if !mysql.HasNotNullFlag(c.Flag) {
return
}
// Check if it is an `AUTO_INCREMENT` field or `TIMESTAMP` field.
if !mysql.HasAutoIncrementFlag(c.Flag) && !mysql.HasTimestampFlag(c.Flag) {
c.Flag |= mysql.NoDefaultValueFlag
}
}
func checkDefaultValue(c *column.Col, hasDefaultValue bool) error {
if !hasDefaultValue {
return nil
}
if c.DefaultValue != nil {
return nil
}
// Set not null but default null is invalid.
if mysql.HasNotNullFlag(c.Flag) {
return errors.Errorf("invalid default value for %s", c.Name)
}
return nil
}
func checkDuplicateColumn(colDefs []*ast.ColumnDef) error {
colNames := map[string]bool{}
for _, colDef := range colDefs {
nameLower := colDef.Name.Name.O
if colNames[nameLower] {
return errors.Errorf("CREATE TABLE: duplicate column %s", colDef.Name)
}
colNames[nameLower] = true
}
return nil
}
func checkConstraintNames(constraints []*ast.Constraint) error {
constrNames := map[string]bool{}
// Check not empty constraint name whether is duplicated.
for _, constr := range constraints {
if constr.Tp == ast.ConstraintForeignKey {
// Ignore foreign key.
continue
}
if constr.Name != "" {
nameLower := strings.ToLower(constr.Name)
if constrNames[nameLower] {
return errors.Errorf("CREATE TABLE: duplicate key %s", constr.Name)
}
constrNames[nameLower] = true
}
}
// Set empty constraint names.
for _, constr := range constraints {
if constr.Name == "" && len(constr.Keys) > 0 {
colName := constr.Keys[0].Column.Name.O
constrName := colName
i := 2
for constrNames[strings.ToLower(constrName)] {
// We loop forever until we find constrName that haven't been used.
constrName = fmt.Sprintf("%s_%d", colName, i)
i++
}
constr.Name = constrName
constrNames[constrName] = true
}
}
return nil
}
func (d *ddl) buildTableInfo(tableName model.CIStr, cols []*column.Col, constraints []*ast.Constraint) (tbInfo *model.TableInfo, err error) {
tbInfo = &model.TableInfo{
Name: tableName,
}
tbInfo.ID, err = d.genGlobalID()
if err != nil {
return nil, errors.Trace(err)
}
for _, v := range cols {
tbInfo.Columns = append(tbInfo.Columns, &v.ColumnInfo)
}
for _, constr := range constraints {
if constr.Tp == ast.ConstraintPrimaryKey {
if len(constr.Keys) == 1 {
key := constr.Keys[0]
col := column.FindCol(cols, key.Column.Name.O)
if col == nil {
return nil, errors.Errorf("No such column: %v", key)
}
switch col.Tp {
case mysql.TypeLong, mysql.TypeLonglong:
tbInfo.PKIsHandle = true
// Avoid creating index for PK handle column.
continue
}
}
}
// 1. check if the column is exists
// 2. add index
indexColumns := make([]*model.IndexColumn, 0, len(constr.Keys))
for _, key := range constr.Keys {
col := column.FindCol(cols, key.Column.Name.O)
if col == nil {
return nil, errors.Errorf("No such column: %v", key)
}
indexColumns = append(indexColumns, &model.IndexColumn{
Name: key.Column.Name,
Offset: col.Offset,
Length: key.Length,
})
}
idxInfo := &model.IndexInfo{
Name: model.NewCIStr(constr.Name),
Columns: indexColumns,
State: model.StatePublic,
}
switch constr.Tp {
case ast.ConstraintPrimaryKey:
idxInfo.Unique = true
idxInfo.Primary = true
idxInfo.Name = model.NewCIStr(column.PrimaryKeyName)
case ast.ConstraintUniq, ast.ConstraintUniqKey, ast.ConstraintUniqIndex:
idxInfo.Unique = true
}
if constr.Option != nil {
idxInfo.Comment = constr.Option.Comment
idxInfo.Tp = constr.Option.Tp
} else {
// Use btree as default index type.
idxInfo.Tp = model.IndexTypeBtree
}
idxInfo.ID, err = d.genGlobalID()
if err != nil {
return nil, errors.Trace(err)
}
tbInfo.Indices = append(tbInfo.Indices, idxInfo)
}
return
}
func (d *ddl) CreateTable(ctx context.Context, ident ast.Ident, colDefs []*ast.ColumnDef,
constraints []*ast.Constraint, options []*ast.TableOption) (err error) {
is := d.GetInformationSchema()
schema, ok := is.SchemaByName(ident.Schema)
if !ok {
return infoschema.DatabaseNotExists.Gen("database %s not exists", ident.Schema)
}
if is.TableExists(ident.Schema, ident.Name) {
return errors.Trace(infoschema.TableExists)
}
if err = checkDuplicateColumn(colDefs); err != nil {
return errors.Trace(err)
}
cols, newConstraints, err := d.buildColumnsAndConstraints(ctx, colDefs, constraints)
if err != nil {
return errors.Trace(err)
}
err = checkConstraintNames(newConstraints)
if err != nil {
return errors.Trace(err)
}
tbInfo, err := d.buildTableInfo(ident.Name, cols, newConstraints)
if err != nil {
return errors.Trace(err)
}
job := &model.Job{
SchemaID: schema.ID,
TableID: tbInfo.ID,
Type: model.ActionCreateTable,
Args: []interface{}{tbInfo},
}
err = d.startDDLJob(ctx, job)
if err == nil {
err = d.handleTableOptions(options, tbInfo, schema.ID)
}
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
func (d *ddl) handleTableOptions(options []*ast.TableOption, tbInfo *model.TableInfo, schemaID int64) error {
for _, op := range options {
if op.Tp == ast.TableOptionAutoIncrement {
alloc := autoid.NewAllocator(d.store, schemaID)
tbInfo.State = model.StatePublic
tb, err := table.TableFromMeta(alloc, tbInfo)
if err != nil {
return errors.Trace(err)
}
// The operation of the minus 1 to make sure that the current value doesn't be used,
// the next Alloc operation will get this value.
// Its behavior is consistent with MySQL.
if err = tb.RebaseAutoID(int64(op.UintValue-1), false); err != nil {
return errors.Trace(err)
}
}
}
return nil
}
func (d *ddl) AlterTable(ctx context.Context, ident ast.Ident, specs []*ast.AlterTableSpec) (err error) {
// now we only allow one schema changes at the same time.
if len(specs) != 1 {
return errors.New("can't run multi schema changes in one DDL")
}
for _, spec := range specs {
switch spec.Tp {
case ast.AlterTableAddColumn:
err = d.AddColumn(ctx, ident, spec)
case ast.AlterTableDropColumn:
err = d.DropColumn(ctx, ident, spec.DropColumn.Name)
case ast.AlterTableDropIndex:
err = d.DropIndex(ctx, ident, model.NewCIStr(spec.Name))
case ast.AlterTableAddConstraint:
constr := spec.Constraint
switch spec.Constraint.Tp {
case ast.ConstraintKey, ast.ConstraintIndex:
err = d.CreateIndex(ctx, ident, false, model.NewCIStr(constr.Name), spec.Constraint.Keys)
case ast.ConstraintUniq, ast.ConstraintUniqIndex, ast.ConstraintUniqKey:
err = d.CreateIndex(ctx, ident, true, model.NewCIStr(constr.Name), spec.Constraint.Keys)
default:
// nothing to do now.
}
default:
// nothing to do now.
}
if err != nil {
return errors.Trace(err)
}
}
return nil
}
func checkColumnConstraint(constraints []*ast.ColumnOption) error {
for _, constraint := range constraints {
switch constraint.Tp {
case ast.ColumnOptionAutoIncrement, ast.ColumnOptionPrimaryKey, ast.ColumnOptionUniq, ast.ColumnOptionUniqKey:
return errors.Errorf("unsupported add column constraint - %v", constraint.Tp)
}
}
return nil
}
// AddColumn will add a new column to the table.
func (d *ddl) AddColumn(ctx context.Context, ti ast.Ident, spec *ast.AlterTableSpec) error {
// Check whether the added column constraints are supported.
err := checkColumnConstraint(spec.Column.Options)
if err != nil {
return errors.Trace(err)
}
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return errors.Trace(infoschema.DatabaseNotExists)
}
t, err := is.TableByName(ti.Schema, ti.Name)
if err != nil {
return errors.Trace(infoschema.TableNotExists)
}
// Check whether added column has existed.
colName := spec.Column.Name.Name.O
col := column.FindCol(t.Cols(), colName)
if col != nil {
return errors.Errorf("column %s already exists", colName)
}
// ingore table constraints now, maybe return error later
// we use length(t.Cols()) as the default offset first, later we will change the
// column's offset later.
col, _, err = d.buildColumnAndConstraint(ctx, len(t.Cols()), spec.Column)
if err != nil {
return errors.Trace(err)
}
job := &model.Job{
SchemaID: schema.ID,
TableID: t.Meta().ID,
Type: model.ActionAddColumn,
Args: []interface{}{&col.ColumnInfo, spec.Position, 0},
}
err = d.startDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
// DropColumn will drop a column from the table, now we don't support drop the column with index covered.
func (d *ddl) DropColumn(ctx context.Context, ti ast.Ident, colName model.CIStr) error {
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return errors.Trace(infoschema.DatabaseNotExists)
}
t, err := is.TableByName(ti.Schema, ti.Name)
if err != nil {
return errors.Trace(infoschema.TableNotExists)
}
// Check whether dropped column has existed.
col := column.FindCol(t.Cols(), colName.L)
if col == nil {
return errors.Errorf("column %s doesnt exist", colName.L)
}
job := &model.Job{
SchemaID: schema.ID,
TableID: t.Meta().ID,
Type: model.ActionDropColumn,
Args: []interface{}{colName},
}
err = d.startDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
// DropTable will proceed even if some table in the list does not exists.
func (d *ddl) DropTable(ctx context.Context, ti ast.Ident) (err error) {
is := d.GetInformationSchema()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return infoschema.DatabaseNotExists.Gen("database %s not exists", ti.Schema)
}
tb, err := is.TableByName(ti.Schema, ti.Name)
if err != nil {
return errors.Trace(infoschema.TableNotExists)
}
job := &model.Job{
SchemaID: schema.ID,
TableID: tb.Meta().ID,
Type: model.ActionDropTable,
}
err = d.startDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
func (d *ddl) CreateIndex(ctx context.Context, ti ast.Ident, unique bool, indexName model.CIStr, idxColNames []*ast.IndexColName) error {
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return infoschema.DatabaseNotExists.Gen("database %s not exists", ti.Schema)
}
t, err := is.TableByName(ti.Schema, ti.Name)
if err != nil {
return errors.Trace(infoschema.TableNotExists)
}
indexID, err := d.genGlobalID()
if err != nil {
return errors.Trace(err)
}
job := &model.Job{
SchemaID: schema.ID,
TableID: t.Meta().ID,
Type: model.ActionAddIndex,
Args: []interface{}{unique, indexName, indexID, idxColNames},
}
err = d.startDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
func (d *ddl) DropIndex(ctx context.Context, ti ast.Ident, indexName model.CIStr) error {
is := d.infoHandle.Get()
schema, ok := is.SchemaByName(ti.Schema)
if !ok {
return errors.Trace(infoschema.DatabaseNotExists)
}
t, err := is.TableByName(ti.Schema, ti.Name)
if err != nil {
return errors.Trace(infoschema.TableNotExists)
}
job := &model.Job{
SchemaID: schema.ID,
TableID: t.Meta().ID,
Type: model.ActionDropIndex,
Args: []interface{}{indexName},
}
err = d.startDDLJob(ctx, job)
err = d.hook.OnChanged(err)
return errors.Trace(err)
}
// findCol finds column in cols by name.
func findCol(cols []*model.ColumnInfo, name string) *model.ColumnInfo {
name = strings.ToLower(name)
for _, col := range cols {
if col.Name.L == name {
return col
}
}
return nil
}

392
vendor/github.com/pingcap/tidb/ddl/ddl_worker.go generated vendored Normal file
View file

@ -0,0 +1,392 @@
// 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 ddl
import (
"time"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/terror"
)
func (d *ddl) startDDLJob(ctx context.Context, job *model.Job) error {
// for every DDL, we must commit current transaction.
if err := ctx.FinishTxn(false); err != nil {
return errors.Trace(err)
}
// Create a new job and queue it.
err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
t := meta.NewMeta(txn)
var err error
job.ID, err = t.GenGlobalID()
if err != nil {
return errors.Trace(err)
}
err = t.EnQueueDDLJob(job)
return errors.Trace(err)
})
if err != nil {
return errors.Trace(err)
}
// notice worker that we push a new job and wait the job done.
asyncNotify(d.ddlJobCh)
log.Warnf("[ddl] start DDL job %v", job)
jobID := job.ID
var historyJob *model.Job
// for a job from start to end, the state of it will be none -> delete only -> write only -> reorganization -> public
// for every state changes, we will wait as lease 2 * lease time, so here the ticker check is 10 * lease.
ticker := time.NewTicker(chooseLeaseTime(10*d.lease, 10*time.Second))
defer ticker.Stop()
for {
select {
case <-d.ddlJobDoneCh:
case <-ticker.C:
}
historyJob, err = d.getHistoryDDLJob(jobID)
if err != nil {
log.Errorf("[ddl] get history DDL job err %v, check again", err)
continue
} else if historyJob == nil {
log.Warnf("[ddl] DDL job %d is not in history, maybe not run", jobID)
continue
}
// if a job is a history table, the state must be JobDone or JobCancel.
if historyJob.State == model.JobDone {
return nil
}
return errors.Errorf(historyJob.Error)
}
}
func (d *ddl) getHistoryDDLJob(id int64) (*model.Job, error) {
var job *model.Job
err := kv.RunInNewTxn(d.store, false, func(txn kv.Transaction) error {
t := meta.NewMeta(txn)
var err1 error
job, err1 = t.GetHistoryDDLJob(id)
return errors.Trace(err1)
})
return job, errors.Trace(err)
}
func asyncNotify(ch chan struct{}) {
select {
case ch <- struct{}{}:
default:
}
}
func (d *ddl) checkOwner(t *meta.Meta, flag JobType) (*model.Owner, error) {
var owner *model.Owner
var err error
switch flag {
case ddlJobFlag:
owner, err = t.GetDDLJobOwner()
case bgJobFlag:
owner, err = t.GetBgJobOwner()
default:
err = errInvalidJobFlag
}
if err != nil {
return nil, errors.Trace(err)
}
if owner == nil {
owner = &model.Owner{}
// try to set onwer
owner.OwnerID = d.uuid
}
now := time.Now().UnixNano()
// we must wait 2 * lease time to guarantee other servers update the schema,
// the owner will update its owner status every 2 * lease time, so here we use
// 4 * lease to check its timeout.
maxTimeout := int64(4 * d.lease)
if owner.OwnerID == d.uuid || now-owner.LastUpdateTS > maxTimeout {
owner.OwnerID = d.uuid
owner.LastUpdateTS = now
// update status.
switch flag {
case ddlJobFlag:
err = t.SetDDLJobOwner(owner)
case bgJobFlag:
err = t.SetBgJobOwner(owner)
}
if err != nil {
return nil, errors.Trace(err)
}
log.Debugf("[ddl] become %s job owner %s", flag, owner.OwnerID)
}
if owner.OwnerID != d.uuid {
log.Debugf("[ddl] not %s job owner, owner is %s", flag, owner.OwnerID)
return nil, errors.Trace(ErrNotOwner)
}
return owner, nil
}
func (d *ddl) getFirstDDLJob(t *meta.Meta) (*model.Job, error) {
job, err := t.GetDDLJob(0)
return job, errors.Trace(err)
}
// every time we enter another state except final state, we must call this function.
func (d *ddl) updateDDLJob(t *meta.Meta, job *model.Job) error {
err := t.UpdateDDLJob(0, job)
return errors.Trace(err)
}
func (d *ddl) finishDDLJob(t *meta.Meta, job *model.Job) error {
log.Warnf("[ddl] finish DDL job %v", job)
// done, notice and run next job.
_, err := t.DeQueueDDLJob()
if err != nil {
return errors.Trace(err)
}
switch job.Type {
case model.ActionDropSchema, model.ActionDropTable:
if err = d.prepareBgJob(job); err != nil {
return errors.Trace(err)
}
}
err = t.AddHistoryDDLJob(job)
return errors.Trace(err)
}
// ErrNotOwner means we are not owner and can't handle DDL jobs.
var ErrNotOwner = errors.New("DDL: not owner")
// ErrWorkerClosed means we have already closed the DDL worker.
var ErrWorkerClosed = errors.New("DDL: worker is closed")
var errInvalidJobFlag = errors.New("DDL: invalid job flag")
// JobType is job type, including ddl/background.
type JobType int
const (
ddlJobFlag = iota + 1
bgJobFlag
)
func (j JobType) String() string {
switch j {
case ddlJobFlag:
return "ddl"
case bgJobFlag:
return "background"
}
return "unknown"
}
func (d *ddl) handleDDLJobQueue() error {
for {
if d.isClosed() {
return nil
}
waitTime := 2 * d.lease
var job *model.Job
err := kv.RunInNewTxn(d.store, false, func(txn kv.Transaction) error {
t := meta.NewMeta(txn)
owner, err := d.checkOwner(t, ddlJobFlag)
if terror.ErrorEqual(err, ErrNotOwner) {
// we are not owner, return and retry checking later.
return nil
} else if err != nil {
return errors.Trace(err)
}
// become the owner
// get the first job and run
job, err = d.getFirstDDLJob(t)
if job == nil || err != nil {
return errors.Trace(err)
}
if job.IsRunning() {
// if we enter a new state, crash when waiting 2 * lease time, and restart quickly,
// we may run the job immediately again, but we don't wait enough 2 * lease time to
// let other servers update the schema.
// so here we must check the elapsed time from last update, if < 2 * lease, we must
// wait again.
elapsed := time.Duration(time.Now().UnixNano() - job.LastUpdateTS)
if elapsed > 0 && elapsed < waitTime {
log.Warnf("[ddl] the elapsed time from last update is %s < %s, wait again", elapsed, waitTime)
waitTime -= elapsed
return nil
}
}
log.Warnf("[ddl] run DDL job %v", job)
d.hook.OnJobRunBefore(job)
// if run job meets error, we will save this error in job Error
// and retry later if the job is not cancelled.
d.runDDLJob(t, job)
if job.IsFinished() {
err = d.finishDDLJob(t, job)
} else {
err = d.updateDDLJob(t, job)
}
if err != nil {
return errors.Trace(err)
}
// running job may cost some time, so here we must update owner status to
// prevent other become the owner.
owner.LastUpdateTS = time.Now().UnixNano()
err = t.SetDDLJobOwner(owner)
return errors.Trace(err)
})
if err != nil {
return errors.Trace(err)
} else if job == nil {
// no job now, return and retry get later.
return nil
}
d.hook.OnJobUpdated(job)
// here means the job enters another state (delete only, write only, public, etc...) or is cancelled.
// if the job is done or still running, we will wait 2 * lease time to guarantee other servers to update
// the newest schema.
if job.State == model.JobRunning || job.State == model.JobDone {
d.waitSchemaChanged(waitTime)
}
if job.IsFinished() {
d.startBgJob(job.Type)
asyncNotify(d.ddlJobDoneCh)
}
}
}
func chooseLeaseTime(n1 time.Duration, n2 time.Duration) time.Duration {
if n1 > 0 {
return n1
}
return n2
}
// onDDLWorker is for async online schema change, it will try to become the owner first,
// then wait or pull the job queue to handle a schema change job.
func (d *ddl) onDDLWorker() {
defer d.wait.Done()
// we use 4 * lease time to check owner's timeout, so here, we will update owner's status
// every 2 * lease time, if lease is 0, we will use default 10s.
checkTime := chooseLeaseTime(2*d.lease, 10*time.Second)
ticker := time.NewTicker(checkTime)
defer ticker.Stop()
for {
select {
case <-ticker.C:
log.Debugf("[ddl] wait %s to check DDL status again", checkTime)
case <-d.ddlJobCh:
case <-d.quitCh:
return
}
err := d.handleDDLJobQueue()
if err != nil {
log.Errorf("[ddl] handle ddl job err %v", errors.ErrorStack(err))
}
}
}
func (d *ddl) runDDLJob(t *meta.Meta, job *model.Job) {
if job.IsFinished() {
return
}
job.State = model.JobRunning
var err error
switch job.Type {
case model.ActionCreateSchema:
err = d.onCreateSchema(t, job)
case model.ActionDropSchema:
err = d.onDropSchema(t, job)
case model.ActionCreateTable:
err = d.onCreateTable(t, job)
case model.ActionDropTable:
err = d.onDropTable(t, job)
case model.ActionAddColumn:
err = d.onAddColumn(t, job)
case model.ActionDropColumn:
err = d.onDropColumn(t, job)
case model.ActionAddIndex:
err = d.onCreateIndex(t, job)
case model.ActionDropIndex:
err = d.onDropIndex(t, job)
default:
// invalid job, cancel it.
job.State = model.JobCancelled
err = errors.Errorf("invalid ddl job %v", job)
}
// saves error in job, so that others can know error happens.
if err != nil {
// if job is not cancelled, we should log this error.
if job.State != model.JobCancelled {
log.Errorf("run ddl job err %v", errors.ErrorStack(err))
}
job.Error = err.Error()
job.ErrorCount++
}
}
// for every lease seconds, we will re-update the whole schema, so we will wait 2 * lease time
// to guarantee that all servers have already updated schema.
func (d *ddl) waitSchemaChanged(waitTime time.Duration) {
if waitTime == 0 {
return
}
select {
case <-time.After(waitTime):
case <-d.quitCh:
}
}

473
vendor/github.com/pingcap/tidb/ddl/index.go generated vendored Normal file
View file

@ -0,0 +1,473 @@
// 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 ddl
import (
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/table/tables"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util"
"github.com/pingcap/tidb/util/types"
)
func buildIndexInfo(tblInfo *model.TableInfo, unique bool, indexName model.CIStr, indexID int64, idxColNames []*ast.IndexColName) (*model.IndexInfo, error) {
// build offsets
idxColumns := make([]*model.IndexColumn, 0, len(idxColNames))
for _, ic := range idxColNames {
col := findCol(tblInfo.Columns, ic.Column.Name.O)
if col == nil {
return nil, errors.Errorf("CREATE INDEX: column does not exist: %s", ic.Column.Name.O)
}
idxColumns = append(idxColumns, &model.IndexColumn{
Name: col.Name,
Offset: col.Offset,
Length: ic.Length,
})
}
// create index info
idxInfo := &model.IndexInfo{
ID: indexID,
Name: indexName,
Columns: idxColumns,
Unique: unique,
State: model.StateNone,
}
return idxInfo, nil
}
func addIndexColumnFlag(tblInfo *model.TableInfo, indexInfo *model.IndexInfo) {
col := indexInfo.Columns[0]
if indexInfo.Unique && len(indexInfo.Columns) == 1 {
tblInfo.Columns[col.Offset].Flag |= mysql.UniqueKeyFlag
} else {
tblInfo.Columns[col.Offset].Flag |= mysql.MultipleKeyFlag
}
}
func dropIndexColumnFlag(tblInfo *model.TableInfo, indexInfo *model.IndexInfo) {
col := indexInfo.Columns[0]
if indexInfo.Unique && len(indexInfo.Columns) == 1 {
tblInfo.Columns[col.Offset].Flag &= ^uint(mysql.UniqueKeyFlag)
} else {
tblInfo.Columns[col.Offset].Flag &= ^uint(mysql.MultipleKeyFlag)
}
// other index may still cover this col
for _, index := range tblInfo.Indices {
if index.Name.L == indexInfo.Name.L {
continue
}
if index.Columns[0].Name.L != col.Name.L {
continue
}
addIndexColumnFlag(tblInfo, index)
}
}
func (d *ddl) onCreateIndex(t *meta.Meta, job *model.Job) error {
schemaID := job.SchemaID
tblInfo, err := d.getTableInfo(t, job)
if err != nil {
return errors.Trace(err)
}
var (
unique bool
indexName model.CIStr
indexID int64
idxColNames []*ast.IndexColName
)
err = job.DecodeArgs(&unique, &indexName, &indexID, &idxColNames)
if err != nil {
job.State = model.JobCancelled
return errors.Trace(err)
}
var indexInfo *model.IndexInfo
for _, idx := range tblInfo.Indices {
if idx.Name.L == indexName.L {
if idx.State == model.StatePublic {
// we already have a index with same index name
job.State = model.JobCancelled
return errors.Errorf("CREATE INDEX: index already exist %s", indexName)
}
indexInfo = idx
}
}
if indexInfo == nil {
indexInfo, err = buildIndexInfo(tblInfo, unique, indexName, indexID, idxColNames)
if err != nil {
job.State = model.JobCancelled
return errors.Trace(err)
}
tblInfo.Indices = append(tblInfo.Indices, indexInfo)
}
_, err = t.GenSchemaVersion()
if err != nil {
return errors.Trace(err)
}
switch indexInfo.State {
case model.StateNone:
// none -> delete only
job.SchemaState = model.StateDeleteOnly
indexInfo.State = model.StateDeleteOnly
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateDeleteOnly:
// delete only -> write only
job.SchemaState = model.StateWriteOnly
indexInfo.State = model.StateWriteOnly
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateWriteOnly:
// write only -> reorganization
job.SchemaState = model.StateWriteReorganization
indexInfo.State = model.StateWriteReorganization
// initialize SnapshotVer to 0 for later reorganization check.
job.SnapshotVer = 0
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateWriteReorganization:
// reorganization -> public
reorgInfo, err := d.getReorgInfo(t, job)
if err != nil || reorgInfo.first {
// if we run reorg firstly, we should update the job snapshot version
// and then run the reorg next time.
return errors.Trace(err)
}
var tbl table.Table
tbl, err = d.getTable(schemaID, tblInfo)
if err != nil {
return errors.Trace(err)
}
err = d.runReorgJob(func() error {
return d.addTableIndex(tbl, indexInfo, reorgInfo)
})
if terror.ErrorEqual(err, errWaitReorgTimeout) {
// if timeout, we should return, check for the owner and re-wait job done.
return nil
}
if err != nil {
return errors.Trace(err)
}
indexInfo.State = model.StatePublic
// set column index flag.
addIndexColumnFlag(tblInfo, indexInfo)
if err = t.UpdateTable(schemaID, tblInfo); err != nil {
return errors.Trace(err)
}
// finish this job
job.SchemaState = model.StatePublic
job.State = model.JobDone
return nil
default:
return errors.Errorf("invalid index state %v", tblInfo.State)
}
}
func (d *ddl) onDropIndex(t *meta.Meta, job *model.Job) error {
schemaID := job.SchemaID
tblInfo, err := d.getTableInfo(t, job)
if err != nil {
return errors.Trace(err)
}
var indexName model.CIStr
if err = job.DecodeArgs(&indexName); err != nil {
job.State = model.JobCancelled
return errors.Trace(err)
}
var indexInfo *model.IndexInfo
for _, idx := range tblInfo.Indices {
if idx.Name.L == indexName.L {
indexInfo = idx
}
}
if indexInfo == nil {
job.State = model.JobCancelled
return errors.Errorf("index %s doesn't exist", indexName)
}
_, err = t.GenSchemaVersion()
if err != nil {
return errors.Trace(err)
}
switch indexInfo.State {
case model.StatePublic:
// public -> write only
job.SchemaState = model.StateWriteOnly
indexInfo.State = model.StateWriteOnly
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateWriteOnly:
// write only -> delete only
job.SchemaState = model.StateDeleteOnly
indexInfo.State = model.StateDeleteOnly
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateDeleteOnly:
// delete only -> reorganization
job.SchemaState = model.StateDeleteReorganization
indexInfo.State = model.StateDeleteReorganization
err = t.UpdateTable(schemaID, tblInfo)
return errors.Trace(err)
case model.StateDeleteReorganization:
// reorganization -> absent
tbl, err := d.getTable(schemaID, tblInfo)
if err != nil {
return errors.Trace(err)
}
err = d.runReorgJob(func() error {
return d.dropTableIndex(tbl, indexInfo)
})
if terror.ErrorEqual(err, errWaitReorgTimeout) {
// if timeout, we should return, check for the owner and re-wait job done.
return nil
}
if err != nil {
return errors.Trace(err)
}
// all reorganization jobs done, drop this index
newIndices := make([]*model.IndexInfo, 0, len(tblInfo.Indices))
for _, idx := range tblInfo.Indices {
if idx.Name.L != indexName.L {
newIndices = append(newIndices, idx)
}
}
tblInfo.Indices = newIndices
// set column index flag.
dropIndexColumnFlag(tblInfo, indexInfo)
if err = t.UpdateTable(schemaID, tblInfo); err != nil {
return errors.Trace(err)
}
// finish this job
job.SchemaState = model.StateNone
job.State = model.JobDone
return nil
default:
return errors.Errorf("invalid table state %v", tblInfo.State)
}
}
func checkRowExist(txn kv.Transaction, t table.Table, handle int64) (bool, error) {
_, err := txn.Get(t.RecordKey(handle, nil))
if terror.ErrorEqual(err, kv.ErrNotExist) {
// If row doesn't exist, we may have deleted the row already,
// no need to add index again.
return false, nil
} else if err != nil {
return false, errors.Trace(err)
}
return true, nil
}
func fetchRowColVals(txn kv.Transaction, t table.Table, handle int64, indexInfo *model.IndexInfo) ([]types.Datum, error) {
// fetch datas
cols := t.Cols()
vals := make([]types.Datum, 0, len(indexInfo.Columns))
for _, v := range indexInfo.Columns {
col := cols[v.Offset]
k := t.RecordKey(handle, col)
data, err := txn.Get(k)
if err != nil {
return nil, errors.Trace(err)
}
val, err := tables.DecodeValue(data, &col.FieldType)
if err != nil {
return nil, errors.Trace(err)
}
vals = append(vals, val)
}
return vals, nil
}
const maxBatchSize = 1024
// How to add index in reorganization state?
// 1. Generate a snapshot with special version.
// 2. Traverse the snapshot, get every row in the table.
// 3. For one row, if the row has been already deleted, skip to next row.
// 4. If not deleted, check whether index has existed, if existed, skip to next row.
// 5. If index doesn't exist, create the index and then continue to handle next row.
func (d *ddl) addTableIndex(t table.Table, indexInfo *model.IndexInfo, reorgInfo *reorgInfo) error {
seekHandle := reorgInfo.Handle
version := reorgInfo.SnapshotVer
for {
handles, err := d.getSnapshotRows(t, version, seekHandle)
if err != nil {
return errors.Trace(err)
} else if len(handles) == 0 {
return nil
}
seekHandle = handles[len(handles)-1] + 1
err = d.backfillTableIndex(t, indexInfo, handles, reorgInfo)
if err != nil {
return errors.Trace(err)
}
}
}
func (d *ddl) getSnapshotRows(t table.Table, version uint64, seekHandle int64) ([]int64, error) {
ver := kv.Version{Ver: version}
snap, err := d.store.GetSnapshot(ver)
if err != nil {
return nil, errors.Trace(err)
}
defer snap.Release()
firstKey := t.RecordKey(seekHandle, nil)
it, err := snap.Seek(firstKey)
if err != nil {
return nil, errors.Trace(err)
}
defer it.Close()
handles := make([]int64, 0, maxBatchSize)
for it.Valid() {
if !it.Key().HasPrefix(t.RecordPrefix()) {
break
}
var handle int64
handle, err = tables.DecodeRecordKeyHandle(it.Key())
if err != nil {
return nil, errors.Trace(err)
}
rk := t.RecordKey(handle, nil)
handles = append(handles, handle)
if len(handles) == maxBatchSize {
break
}
err = kv.NextUntil(it, util.RowKeyPrefixFilter(rk))
if terror.ErrorEqual(err, kv.ErrNotExist) {
break
} else if err != nil {
return nil, errors.Trace(err)
}
}
return handles, nil
}
func lockRow(txn kv.Transaction, t table.Table, h int64) error {
// Get row lock key
lockKey := t.RecordKey(h, nil)
// set row lock key to current txn
err := txn.Set(lockKey, []byte(txn.String()))
return errors.Trace(err)
}
func (d *ddl) backfillTableIndex(t table.Table, indexInfo *model.IndexInfo, handles []int64, reorgInfo *reorgInfo) error {
kvX := kv.NewKVIndex(t.IndexPrefix(), indexInfo.Name.L, indexInfo.ID, indexInfo.Unique)
for _, handle := range handles {
log.Debug("[ddl] building index...", handle)
err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
if err := d.isReorgRunnable(txn); err != nil {
return errors.Trace(err)
}
// first check row exists
exist, err := checkRowExist(txn, t, handle)
if err != nil {
return errors.Trace(err)
} else if !exist {
// row doesn't exist, skip it.
return nil
}
var vals []types.Datum
vals, err = fetchRowColVals(txn, t, handle, indexInfo)
if err != nil {
return errors.Trace(err)
}
exist, _, err = kvX.Exist(txn, vals, handle)
if err != nil {
return errors.Trace(err)
} else if exist {
// index already exists, skip it.
return nil
}
err = lockRow(txn, t, handle)
if err != nil {
return errors.Trace(err)
}
// create the index.
err = kvX.Create(txn, vals, handle)
if err != nil {
return errors.Trace(err)
}
// update reorg next handle
return errors.Trace(reorgInfo.UpdateHandle(txn, handle))
})
if err != nil {
return errors.Trace(err)
}
}
return nil
}
func (d *ddl) dropTableIndex(t table.Table, indexInfo *model.IndexInfo) error {
prefix := kv.GenIndexPrefix(t.IndexPrefix(), indexInfo.ID)
err := d.delKeysWithPrefix(prefix)
return errors.Trace(err)
}

250
vendor/github.com/pingcap/tidb/ddl/reorg.go generated vendored Normal file
View file

@ -0,0 +1,250 @@
// 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 ddl
import (
"fmt"
"time"
"github.com/juju/errors"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/terror"
)
var _ context.Context = &reorgContext{}
// reorgContext implements context.Context interface for reorganization use.
type reorgContext struct {
store kv.Storage
m map[fmt.Stringer]interface{}
txn kv.Transaction
}
func (c *reorgContext) GetTxn(forceNew bool) (kv.Transaction, error) {
if forceNew {
if c.txn != nil {
if err := c.txn.Commit(); err != nil {
return nil, errors.Trace(err)
}
c.txn = nil
}
}
if c.txn != nil {
return c.txn, nil
}
txn, err := c.store.Begin()
if err != nil {
return nil, errors.Trace(err)
}
c.txn = txn
return c.txn, nil
}
func (c *reorgContext) FinishTxn(rollback bool) error {
if c.txn == nil {
return nil
}
var err error
if rollback {
err = c.txn.Rollback()
} else {
err = c.txn.Commit()
}
c.txn = nil
return errors.Trace(err)
}
func (c *reorgContext) SetValue(key fmt.Stringer, value interface{}) {
c.m[key] = value
}
func (c *reorgContext) Value(key fmt.Stringer) interface{} {
return c.m[key]
}
func (c *reorgContext) ClearValue(key fmt.Stringer) {
delete(c.m, key)
}
func (d *ddl) newReorgContext() context.Context {
c := &reorgContext{
store: d.store,
m: make(map[fmt.Stringer]interface{}),
}
return c
}
const waitReorgTimeout = 10 * time.Second
var errWaitReorgTimeout = errors.New("wait for reorganization timeout")
func (d *ddl) runReorgJob(f func() error) error {
if d.reorgDoneCh == nil {
// start a reorganization job
d.wait.Add(1)
d.reorgDoneCh = make(chan error, 1)
go func() {
defer d.wait.Done()
d.reorgDoneCh <- f()
}()
}
waitTimeout := waitReorgTimeout
// if d.lease is 0, we are using a local storage,
// and we can wait the reorganization to be done here.
// if d.lease > 0, we don't need to wait here because
// we will wait 2 * lease outer and try checking again,
// so we use a very little timeout here.
if d.lease > 0 {
waitTimeout = 1 * time.Millisecond
}
// wait reorganization job done or timeout
select {
case err := <-d.reorgDoneCh:
d.reorgDoneCh = nil
return errors.Trace(err)
case <-d.quitCh:
// we return errWaitReorgTimeout here too, so that outer loop will break.
return errWaitReorgTimeout
case <-time.After(waitTimeout):
// if timeout, we will return, check the owner and retry to wait job done again.
return errWaitReorgTimeout
}
}
func (d *ddl) isReorgRunnable(txn kv.Transaction) error {
if d.isClosed() {
// worker is closed, can't run reorganization.
return errors.Trace(ErrWorkerClosed)
}
t := meta.NewMeta(txn)
owner, err := t.GetDDLJobOwner()
if err != nil {
return errors.Trace(err)
} else if owner == nil || owner.OwnerID != d.uuid {
// if no owner, we will try later, so here just return error.
// or another server is owner, return error too.
return errors.Trace(ErrNotOwner)
}
return nil
}
func (d *ddl) delKeysWithPrefix(prefix kv.Key) error {
for {
keys := make([]kv.Key, 0, maxBatchSize)
err := kv.RunInNewTxn(d.store, true, func(txn kv.Transaction) error {
if err1 := d.isReorgRunnable(txn); err1 != nil {
return errors.Trace(err1)
}
iter, err := txn.Seek(prefix)
if err != nil {
return errors.Trace(err)
}
defer iter.Close()
for i := 0; i < maxBatchSize; i++ {
if iter.Valid() && iter.Key().HasPrefix(prefix) {
keys = append(keys, iter.Key().Clone())
err = iter.Next()
if err != nil {
return errors.Trace(err)
}
} else {
break
}
}
for _, key := range keys {
err := txn.Delete(key)
// must skip ErrNotExist
// if key doesn't exist, skip this error.
if err != nil && !terror.ErrorEqual(err, kv.ErrNotExist) {
return errors.Trace(err)
}
}
return nil
})
if err != nil {
return errors.Trace(err)
}
// delete no keys, return.
if len(keys) == 0 {
return nil
}
}
}
type reorgInfo struct {
*model.Job
Handle int64
d *ddl
first bool
}
func (d *ddl) getReorgInfo(t *meta.Meta, job *model.Job) (*reorgInfo, error) {
var err error
info := &reorgInfo{
Job: job,
d: d,
first: job.SnapshotVer == 0,
}
if info.first {
// get the current version for reorganization if we don't have
var ver kv.Version
ver, err = d.store.CurrentVersion()
if err != nil {
return nil, errors.Trace(err)
} else if ver.Ver <= 0 {
return nil, errors.Errorf("invalid storage current version %d", ver.Ver)
}
job.SnapshotVer = ver.Ver
} else {
info.Handle, err = t.GetDDLReorgHandle(job)
if err != nil {
return nil, errors.Trace(err)
}
}
if info.Handle > 0 {
// we have already handled this handle, so use next
info.Handle++
}
return info, errors.Trace(err)
}
func (r *reorgInfo) UpdateHandle(txn kv.Transaction, handle int64) error {
t := meta.NewMeta(txn)
return errors.Trace(t.UpdateDDLReorgHandle(r.Job, handle))
}

163
vendor/github.com/pingcap/tidb/ddl/schema.go generated vendored Normal file
View file

@ -0,0 +1,163 @@
// 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 ddl
import (
"github.com/juju/errors"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/meta/autoid"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/terror"
)
func (d *ddl) onCreateSchema(t *meta.Meta, job *model.Job) error {
schemaID := job.SchemaID
dbInfo := &model.DBInfo{}
if err := job.DecodeArgs(dbInfo); err != nil {
// arg error, cancel this job.
job.State = model.JobCancelled
return errors.Trace(err)
}
dbInfo.ID = schemaID
dbInfo.State = model.StateNone
dbs, err := t.ListDatabases()
if err != nil {
return errors.Trace(err)
}
for _, db := range dbs {
if db.Name.L == dbInfo.Name.L {
if db.ID != schemaID {
// database exists, can't create, we should cancel this job now.
job.State = model.JobCancelled
return errors.Trace(infoschema.DatabaseExists)
}
dbInfo = db
}
}
_, err = t.GenSchemaVersion()
if err != nil {
return errors.Trace(err)
}
switch dbInfo.State {
case model.StateNone:
// none -> public
job.SchemaState = model.StatePublic
dbInfo.State = model.StatePublic
err = t.CreateDatabase(dbInfo)
if err != nil {
return errors.Trace(err)
}
// finish this job
job.State = model.JobDone
return nil
default:
// we can't enter here.
return errors.Errorf("invalid db state %v", dbInfo.State)
}
}
func (d *ddl) delReorgSchema(t *meta.Meta, job *model.Job) error {
dbInfo := &model.DBInfo{}
if err := job.DecodeArgs(dbInfo); err != nil {
// arg error, cancel this job.
job.State = model.JobCancelled
return errors.Trace(err)
}
tables, err := t.ListTables(dbInfo.ID)
if terror.ErrorEqual(meta.ErrDBNotExists, err) {
job.State = model.JobDone
return nil
}
if err != nil {
return errors.Trace(err)
}
if err = d.dropSchemaData(dbInfo, tables); err != nil {
return errors.Trace(err)
}
// finish this background job
job.SchemaState = model.StateNone
job.State = model.JobDone
return nil
}
func (d *ddl) onDropSchema(t *meta.Meta, job *model.Job) error {
dbInfo, err := t.GetDatabase(job.SchemaID)
if err != nil {
return errors.Trace(err)
}
if dbInfo == nil {
job.State = model.JobCancelled
return errors.Trace(infoschema.DatabaseNotExists)
}
_, err = t.GenSchemaVersion()
if err != nil {
return errors.Trace(err)
}
switch dbInfo.State {
case model.StatePublic:
// public -> write only
job.SchemaState = model.StateWriteOnly
dbInfo.State = model.StateWriteOnly
err = t.UpdateDatabase(dbInfo)
case model.StateWriteOnly:
// write only -> delete only
job.SchemaState = model.StateDeleteOnly
dbInfo.State = model.StateDeleteOnly
err = t.UpdateDatabase(dbInfo)
case model.StateDeleteOnly:
dbInfo.State = model.StateDeleteReorganization
err = t.UpdateDatabase(dbInfo)
if err = t.DropDatabase(dbInfo.ID); err != nil {
break
}
// finish this job
job.Args = []interface{}{dbInfo}
job.State = model.JobDone
job.SchemaState = model.StateNone
default:
// we can't enter here.
err = errors.Errorf("invalid db state %v", dbInfo.State)
}
return errors.Trace(err)
}
func (d *ddl) dropSchemaData(dbInfo *model.DBInfo, tables []*model.TableInfo) error {
for _, tblInfo := range tables {
alloc := autoid.NewAllocator(d.store, dbInfo.ID)
t, err := table.TableFromMeta(alloc, tblInfo)
if err != nil {
return errors.Trace(err)
}
err = d.dropTableData(t)
if err != nil {
return errors.Trace(err)
}
}
return nil
}

123
vendor/github.com/pingcap/tidb/ddl/stat.go generated vendored Normal file
View file

@ -0,0 +1,123 @@
// 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 ddl
import (
"github.com/juju/errors"
"github.com/pingcap/tidb/inspectkv"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/sessionctx/variable"
)
var (
serverID = "server_id"
ddlSchemaVersion = "ddl_schema_version"
ddlOwnerID = "ddl_owner_id"
ddlOwnerLastUpdateTS = "ddl_owner_last_update_ts"
ddlJobID = "ddl_job_id"
ddlJobAction = "ddl_job_action"
ddlJobLastUpdateTS = "ddl_job_last_update_ts"
ddlJobState = "ddl_job_state"
ddlJobError = "ddl_job_error"
ddlJobSchemaState = "ddl_job_schema_state"
ddlJobSchemaID = "ddl_job_schema_id"
ddlJobTableID = "ddl_job_table_id"
ddlJobSnapshotVer = "ddl_job_snapshot_ver"
ddlJobReorgHandle = "ddl_job_reorg_handle"
ddlJobArgs = "ddl_job_args"
bgSchemaVersion = "bg_schema_version"
bgOwnerID = "bg_owner_id"
bgOwnerLastUpdateTS = "bg_owner_last_update_ts"
bgJobID = "bg_job_id"
bgJobAction = "bg_job_action"
bgJobLastUpdateTS = "bg_job_last_update_ts"
bgJobState = "bg_job_state"
bgJobError = "bg_job_error"
bgJobSchemaState = "bg_job_schema_state"
bgJobSchemaID = "bg_job_schema_id"
bgJobTableID = "bg_job_table_id"
bgJobSnapshotVer = "bg_job_snapshot_ver"
bgJobReorgHandle = "bg_job_reorg_handle"
bgJobArgs = "bg_job_args"
)
// GetScope gets the status variables scope.
func (d *ddl) GetScope(status string) variable.ScopeFlag {
// Now ddl status variables scope are all default scope.
return variable.DefaultScopeFlag
}
// Stat returns the DDL statistics.
func (d *ddl) Stats() (map[string]interface{}, error) {
m := make(map[string]interface{})
m[serverID] = d.uuid
var ddlInfo, bgInfo *inspectkv.DDLInfo
err := kv.RunInNewTxn(d.store, false, func(txn kv.Transaction) error {
var err1 error
ddlInfo, err1 = inspectkv.GetDDLInfo(txn)
if err1 != nil {
return errors.Trace(err1)
}
bgInfo, err1 = inspectkv.GetBgDDLInfo(txn)
return errors.Trace(err1)
})
if err != nil {
return nil, errors.Trace(err)
}
m[ddlSchemaVersion] = ddlInfo.SchemaVer
if ddlInfo.Owner != nil {
m[ddlOwnerID] = ddlInfo.Owner.OwnerID
// LastUpdateTS uses nanosecond.
m[ddlOwnerLastUpdateTS] = ddlInfo.Owner.LastUpdateTS / 1e9
}
if ddlInfo.Job != nil {
m[ddlJobID] = ddlInfo.Job.ID
m[ddlJobAction] = ddlInfo.Job.Type.String()
m[ddlJobLastUpdateTS] = ddlInfo.Job.LastUpdateTS / 1e9
m[ddlJobState] = ddlInfo.Job.State.String()
m[ddlJobError] = ddlInfo.Job.Error
m[ddlJobSchemaState] = ddlInfo.Job.SchemaState.String()
m[ddlJobSchemaID] = ddlInfo.Job.SchemaID
m[ddlJobTableID] = ddlInfo.Job.TableID
m[ddlJobSnapshotVer] = ddlInfo.Job.SnapshotVer
m[ddlJobReorgHandle] = ddlInfo.ReorgHandle
m[ddlJobArgs] = ddlInfo.Job.Args
}
// background DDL info
m[bgSchemaVersion] = bgInfo.SchemaVer
if bgInfo.Owner != nil {
m[bgOwnerID] = bgInfo.Owner.OwnerID
// LastUpdateTS uses nanosecond.
m[bgOwnerLastUpdateTS] = bgInfo.Owner.LastUpdateTS / 1e9
}
if bgInfo.Job != nil {
m[bgJobID] = bgInfo.Job.ID
m[bgJobAction] = bgInfo.Job.Type.String()
m[bgJobLastUpdateTS] = bgInfo.Job.LastUpdateTS / 1e9
m[bgJobState] = bgInfo.Job.State.String()
m[bgJobError] = bgInfo.Job.Error
m[bgJobSchemaState] = bgInfo.Job.SchemaState.String()
m[bgJobSchemaID] = bgInfo.Job.SchemaID
m[bgJobTableID] = bgInfo.Job.TableID
m[bgJobSnapshotVer] = bgInfo.Job.SnapshotVer
m[bgJobReorgHandle] = bgInfo.ReorgHandle
m[bgJobArgs] = bgInfo.Job.Args
}
return m, nil
}

194
vendor/github.com/pingcap/tidb/ddl/table.go generated vendored Normal file
View file

@ -0,0 +1,194 @@
// 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 ddl
import (
"github.com/juju/errors"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/meta/autoid"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/table"
"github.com/pingcap/tidb/terror"
)
func (d *ddl) onCreateTable(t *meta.Meta, job *model.Job) error {
schemaID := job.SchemaID
tbInfo := &model.TableInfo{}
if err := job.DecodeArgs(tbInfo); err != nil {
// arg error, cancel this job.
job.State = model.JobCancelled
return errors.Trace(err)
}
tbInfo.State = model.StateNone
tables, err := t.ListTables(schemaID)
if terror.ErrorEqual(err, meta.ErrDBNotExists) {
job.State = model.JobCancelled
return errors.Trace(infoschema.DatabaseNotExists)
} else if err != nil {
return errors.Trace(err)
}
for _, tbl := range tables {
if tbl.Name.L == tbInfo.Name.L {
if tbl.ID != tbInfo.ID {
// table exists, can't create, we should cancel this job now.
job.State = model.JobCancelled
return errors.Trace(infoschema.TableExists)
}
tbInfo = tbl
}
}
_, err = t.GenSchemaVersion()
if err != nil {
return errors.Trace(err)
}
switch tbInfo.State {
case model.StateNone:
// none -> public
job.SchemaState = model.StatePublic
tbInfo.State = model.StatePublic
err = t.CreateTable(schemaID, tbInfo)
if err != nil {
return errors.Trace(err)
}
// finish this job
job.State = model.JobDone
return nil
default:
return errors.Errorf("invalid table state %v", tbInfo.State)
}
}
func (d *ddl) delReorgTable(t *meta.Meta, job *model.Job) error {
tblInfo := &model.TableInfo{}
err := job.DecodeArgs(tblInfo)
if err != nil {
// arg error, cancel this job.
job.State = model.JobCancelled
return errors.Trace(err)
}
tblInfo.State = model.StateDeleteReorganization
tbl, err := d.getTable(job.SchemaID, tblInfo)
if err != nil {
return errors.Trace(err)
}
err = d.dropTableData(tbl)
if err != nil {
return errors.Trace(err)
}
// finish this background job
job.SchemaState = model.StateNone
job.State = model.JobDone
return nil
}
func (d *ddl) onDropTable(t *meta.Meta, job *model.Job) error {
schemaID := job.SchemaID
tableID := job.TableID
tblInfo, err := t.GetTable(schemaID, tableID)
if terror.ErrorEqual(err, meta.ErrDBNotExists) {
job.State = model.JobCancelled
return errors.Trace(infoschema.DatabaseNotExists)
} else if err != nil {
return errors.Trace(err)
}
if tblInfo == nil {
job.State = model.JobCancelled
return errors.Trace(infoschema.TableNotExists)
}
_, err = t.GenSchemaVersion()
if err != nil {
return errors.Trace(err)
}
switch tblInfo.State {
case model.StatePublic:
// public -> write only
job.SchemaState = model.StateWriteOnly
tblInfo.State = model.StateWriteOnly
err = t.UpdateTable(schemaID, tblInfo)
case model.StateWriteOnly:
// write only -> delete only
job.SchemaState = model.StateDeleteOnly
tblInfo.State = model.StateDeleteOnly
err = t.UpdateTable(schemaID, tblInfo)
case model.StateDeleteOnly:
tblInfo.State = model.StateNone
err = t.UpdateTable(schemaID, tblInfo)
if err = t.DropTable(job.SchemaID, job.TableID); err != nil {
break
}
// finish this job
job.Args = []interface{}{tblInfo}
job.State = model.JobDone
job.SchemaState = model.StateNone
default:
err = errors.Errorf("invalid table state %v", tblInfo.State)
}
return errors.Trace(err)
}
func (d *ddl) getTable(schemaID int64, tblInfo *model.TableInfo) (table.Table, error) {
alloc := autoid.NewAllocator(d.store, schemaID)
tbl, err := table.TableFromMeta(alloc, tblInfo)
return tbl, errors.Trace(err)
}
func (d *ddl) getTableInfo(t *meta.Meta, job *model.Job) (*model.TableInfo, error) {
schemaID := job.SchemaID
tableID := job.TableID
tblInfo, err := t.GetTable(schemaID, tableID)
if terror.ErrorEqual(err, meta.ErrDBNotExists) {
job.State = model.JobCancelled
return nil, errors.Trace(infoschema.DatabaseNotExists)
} else if err != nil {
return nil, errors.Trace(err)
} else if tblInfo == nil {
job.State = model.JobCancelled
return nil, errors.Trace(infoschema.TableNotExists)
}
if tblInfo.State != model.StatePublic {
job.State = model.JobCancelled
return nil, errors.Errorf("table %s is not in public, but %s", tblInfo.Name.L, tblInfo.State)
}
return tblInfo, nil
}
func (d *ddl) dropTableData(t table.Table) error {
// delete table data
err := d.delKeysWithPrefix(t.RecordPrefix())
if err != nil {
return errors.Trace(err)
}
// delete table index
err = d.delKeysWithPrefix(t.IndexPrefix())
return errors.Trace(err)
}

270
vendor/github.com/pingcap/tidb/domain/domain.go generated vendored Normal file
View file

@ -0,0 +1,270 @@
// 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 domain
import (
"sync"
"sync/atomic"
"time"
"github.com/juju/errors"
"github.com/ngaut/log"
"github.com/pingcap/tidb/ddl"
"github.com/pingcap/tidb/infoschema"
"github.com/pingcap/tidb/kv"
"github.com/pingcap/tidb/meta"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/sessionctx/variable"
"github.com/pingcap/tidb/store/localstore"
"github.com/pingcap/tidb/terror"
)
var ddlLastReloadSchemaTS = "ddl_last_reload_schema_ts"
// Domain represents a storage space. Different domains can use the same database name.
// Multiple domains can be used in parallel without synchronization.
type Domain struct {
store kv.Storage
infoHandle *infoschema.Handle
ddl ddl.DDL
leaseCh chan time.Duration
// nano seconds
lastLeaseTS int64
m sync.Mutex
}
func (do *Domain) loadInfoSchema(txn kv.Transaction) (err error) {
m := meta.NewMeta(txn)
schemaMetaVersion, err := m.GetSchemaVersion()
if err != nil {
return errors.Trace(err)
}
info := do.infoHandle.Get()
if info != nil && schemaMetaVersion <= info.SchemaMetaVersion() {
// info may be changed by other txn, so here its version may be bigger than schema version,
// so we don't need to reload.
log.Debugf("[ddl] schema version is still %d, no need reload", schemaMetaVersion)
return nil
}
schemas, err := m.ListDatabases()
if err != nil {
return errors.Trace(err)
}
for _, di := range schemas {
if di.State != model.StatePublic {
// schema is not public, can't be used outside.
continue
}
tables, err1 := m.ListTables(di.ID)
if err1 != nil {
return errors.Trace(err1)
}
di.Tables = make([]*model.TableInfo, 0, len(tables))
for _, tbl := range tables {
if tbl.State != model.StatePublic {
// schema is not public, can't be used outsiee.
continue
}
di.Tables = append(di.Tables, tbl)
}
}
log.Infof("[ddl] loadInfoSchema %d", schemaMetaVersion)
err = do.infoHandle.Set(schemas, schemaMetaVersion)
return errors.Trace(err)
}
// InfoSchema gets information schema from domain.
func (do *Domain) InfoSchema() infoschema.InfoSchema {
// try reload if possible.
do.tryReload()
return do.infoHandle.Get()
}
// DDL gets DDL from domain.
func (do *Domain) DDL() ddl.DDL {
return do.ddl
}
// Store gets KV store from domain.
func (do *Domain) Store() kv.Storage {
return do.store
}
// SetLease will reset the lease time for online DDL change.
func (do *Domain) SetLease(lease time.Duration) {
do.leaseCh <- lease
// let ddl to reset lease too.
do.ddl.SetLease(lease)
}
// Stats returns the domain statistic.
func (do *Domain) Stats() (map[string]interface{}, error) {
m := make(map[string]interface{})
m[ddlLastReloadSchemaTS] = atomic.LoadInt64(&do.lastLeaseTS) / 1e9
return m, nil
}
// GetScope gets the status variables scope.
func (do *Domain) GetScope(status string) variable.ScopeFlag {
// Now domain status variables scope are all default scope.
return variable.DefaultScopeFlag
}
func (do *Domain) tryReload() {
// if we don't have update the schema for a long time > lease, we must force reloading it.
// Although we try to reload schema every lease time in a goroutine, sometimes it may not
// run accurately, e.g, the machine has a very high load, running the ticker is delayed.
last := atomic.LoadInt64(&do.lastLeaseTS)
lease := do.ddl.GetLease()
// if lease is 0, we use the local store, so no need to reload.
if lease > 0 && time.Now().UnixNano()-last > lease.Nanoseconds() {
do.mustReload()
}
}
const minReloadTimeout = 20 * time.Second
func (do *Domain) reload() error {
// lock here for only once at same time.
do.m.Lock()
defer do.m.Unlock()
timeout := do.ddl.GetLease() / 2
if timeout < minReloadTimeout {
timeout = minReloadTimeout
}
done := make(chan error, 1)
go func() {
var err error
for {
err = kv.RunInNewTxn(do.store, false, do.loadInfoSchema)
// if err is db closed, we will return it directly, otherwise, we will
// check reloading again.
if terror.ErrorEqual(err, localstore.ErrDBClosed) {
break
}
if err != nil {
log.Errorf("[ddl] load schema err %v, retry again", errors.ErrorStack(err))
// TODO: use a backoff algorithm.
time.Sleep(500 * time.Millisecond)
continue
}
atomic.StoreInt64(&do.lastLeaseTS, time.Now().UnixNano())
break
}
done <- err
}()
select {
case err := <-done:
return errors.Trace(err)
case <-time.After(timeout):
return errors.New("reload schema timeout")
}
}
func (do *Domain) mustReload() {
// if reload error, we will terminate whole program to guarantee data safe.
err := do.reload()
if err != nil {
log.Fatalf("[ddl] reload schema err %v", errors.ErrorStack(err))
}
}
// check schema every 300 seconds default.
const defaultLoadTime = 300 * time.Second
func (do *Domain) loadSchemaInLoop(lease time.Duration) {
if lease <= 0 {
lease = defaultLoadTime
}
ticker := time.NewTicker(lease)
defer ticker.Stop()
for {
select {
case <-ticker.C:
err := do.reload()
// we may close store in test, but the domain load schema loop is still checking,
// so we can't panic for ErrDBClosed and just return here.
if terror.ErrorEqual(err, localstore.ErrDBClosed) {
return
} else if err != nil {
log.Fatalf("[ddl] reload schema err %v", errors.ErrorStack(err))
}
case newLease := <-do.leaseCh:
if newLease <= 0 {
newLease = defaultLoadTime
}
if lease == newLease {
// nothing to do
continue
}
lease = newLease
// reset ticker too.
ticker.Stop()
ticker = time.NewTicker(lease)
}
}
}
type ddlCallback struct {
ddl.BaseCallback
do *Domain
}
func (c *ddlCallback) OnChanged(err error) error {
if err != nil {
return err
}
log.Warnf("[ddl] on DDL change")
c.do.mustReload()
return nil
}
// NewDomain creates a new domain.
func NewDomain(store kv.Storage, lease time.Duration) (d *Domain, err error) {
d = &Domain{
store: store,
leaseCh: make(chan time.Duration, 1),
}
d.infoHandle = infoschema.NewHandle(d.store)
d.ddl = ddl.NewDDL(d.store, d.infoHandle, &ddlCallback{do: d}, lease)
d.mustReload()
variable.RegisterStatistics(d)
go d.loadSchemaInLoop(lease)
return d, nil
}

560
vendor/github.com/pingcap/tidb/driver.go generated vendored Normal file
View file

@ -0,0 +1,560 @@
// Copyright 2013 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSES/QL-LICENSE file.
// 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.
// database/sql/driver
package tidb
import (
"database/sql"
"database/sql/driver"
"io"
"net/url"
"path/filepath"
"strings"
"sync"
"github.com/juju/errors"
"github.com/pingcap/tidb/ast"
"github.com/pingcap/tidb/model"
"github.com/pingcap/tidb/sessionctx"
"github.com/pingcap/tidb/terror"
"github.com/pingcap/tidb/util/types"
)
const (
// DriverName is name of TiDB driver.
DriverName = "tidb"
)
var (
_ driver.Conn = (*driverConn)(nil)
_ driver.Execer = (*driverConn)(nil)
_ driver.Queryer = (*driverConn)(nil)
_ driver.Tx = (*driverConn)(nil)
_ driver.Result = (*driverResult)(nil)
_ driver.Rows = (*driverRows)(nil)
_ driver.Stmt = (*driverStmt)(nil)
_ driver.Driver = (*sqlDriver)(nil)
txBeginSQL = "BEGIN;"
txCommitSQL = "COMMIT;"
txRollbackSQL = "ROLLBACK;"
errNoResult = errors.New("query statement does not produce a result set (no top level SELECT)")
)
type errList []error
type driverParams struct {
storePath string
dbName string
// when set to true `mysql.Time` isn't encoded as string but passed as `time.Time`
// this option is named for compatibility the same as in the mysql driver
// while we actually do not have additional parsing to do
parseTime bool
}
func (e *errList) append(err error) {
if err != nil {
*e = append(*e, err)
}
}
func (e errList) error() error {
if len(e) == 0 {
return nil
}
return e
}
func (e errList) Error() string {
a := make([]string, len(e))
for i, v := range e {
a[i] = v.Error()
}
return strings.Join(a, "\n")
}
func params(args []driver.Value) []interface{} {
r := make([]interface{}, len(args))
for i, v := range args {
r[i] = interface{}(v)
}
return r
}
var (
tidbDriver = &sqlDriver{}
driverOnce sync.Once
)
// RegisterDriver registers TiDB driver.
// The name argument can be optionally prefixed by "engine://". In that case the
// prefix is recognized as a storage engine name.
//
// The name argument can be optionally prefixed by "memory://". In that case
// the prefix is stripped before interpreting it as a name of a memory-only,
// volatile DB.
//
// [0]: http://golang.org/pkg/database/sql/driver/
func RegisterDriver() {
driverOnce.Do(func() { sql.Register(DriverName, tidbDriver) })
}
// sqlDriver implements the interface required by database/sql/driver.
type sqlDriver struct {
mu sync.Mutex
}
func (d *sqlDriver) lock() {
d.mu.Lock()
}
func (d *sqlDriver) unlock() {
d.mu.Unlock()
}
// parseDriverDSN cuts off DB name from dsn. It returns error if the dsn is not
// valid.
func parseDriverDSN(dsn string) (params *driverParams, err error) {
u, err := url.Parse(dsn)
if err != nil {
return nil, errors.Trace(err)
}
path := filepath.Join(u.Host, u.Path)
dbName := filepath.Clean(filepath.Base(path))
if dbName == "" || dbName == "." || dbName == string(filepath.Separator) {
return nil, errors.Errorf("invalid DB name %q", dbName)
}
// cut off dbName
path = filepath.Clean(filepath.Dir(path))
if path == "" || path == "." || path == string(filepath.Separator) {
return nil, errors.Errorf("invalid dsn %q", dsn)
}
u.Path, u.Host = path, ""
params = &driverParams{
storePath: u.String(),
dbName: dbName,
}
// parse additional driver params
query := u.Query()
if parseTime := query.Get("parseTime"); parseTime == "true" {
params.parseTime = true
}
return params, nil
}
// Open returns a new connection to the database.
//
// The dsn must be a URL format 'engine://path/dbname?params'.
// Engine is the storage name registered with RegisterStore.
// Path is the storage specific format.
// Params is key-value pairs split by '&', optional params are storage specific.
// Examples:
// goleveldb://relative/path/test
// boltdb:///absolute/path/test
// hbase://zk1,zk2,zk3/hbasetbl/test?tso=zk
//
// Open may return a cached connection (one previously closed), but doing so is
// unnecessary; the sql package maintains a pool of idle connections for
// efficient re-use.
//
// The behavior of the mysql driver regarding time parsing can also be imitated
// by passing ?parseTime
//
// The returned connection is only used by one goroutine at a time.
func (d *sqlDriver) Open(dsn string) (driver.Conn, error) {
params, err := parseDriverDSN(dsn)
if err != nil {
return nil, errors.Trace(err)
}
store, err := NewStore(params.storePath)
if err != nil {
return nil, errors.Trace(err)
}
sess, err := CreateSession(store)
if err != nil {
return nil, errors.Trace(err)
}
s := sess.(*session)
d.lock()
defer d.unlock()
DBName := model.NewCIStr(params.dbName)
domain := sessionctx.GetDomain(s)
cs := &ast.CharsetOpt{
Chs: "utf8",
Col: "utf8_bin",
}
if !domain.InfoSchema().SchemaExists(DBName) {
err = domain.DDL().CreateSchema(s, DBName, cs)
if err != nil {
return nil, errors.Trace(err)
}
}
driver := &sqlDriver{}
return newDriverConn(s, driver, DBName.O, params)
}
// driverConn is a connection to a database. It is not used concurrently by
// multiple goroutines.
//
// Conn is assumed to be stateful.
type driverConn struct {
s Session
driver *sqlDriver
stmts map[string]driver.Stmt
params *driverParams
}
func newDriverConn(sess *session, d *sqlDriver, schema string, params *driverParams) (driver.Conn, error) {
r := &driverConn{
driver: d,
stmts: map[string]driver.Stmt{},
s: sess,
params: params,
}
_, err := r.s.Execute("use " + schema)
if err != nil {
return nil, errors.Trace(err)
}
return r, nil
}
// Prepare returns a prepared statement, bound to this connection.
func (c *driverConn) Prepare(query string) (driver.Stmt, error) {
stmtID, paramCount, fields, err := c.s.PrepareStmt(query)
if err != nil {
return nil, err
}
s := &driverStmt{
conn: c,
query: query,
stmtID: stmtID,
paramCount: paramCount,
isQuery: fields != nil,
}
c.stmts[query] = s
return s, nil
}
// Close invalidates and potentially stops any current prepared statements and
// transactions, marking this connection as no longer in use.
//
// Because the sql package maintains a free pool of connections and only calls
// Close when there's a surplus of idle connections, it shouldn't be necessary
// for drivers to do their own connection caching.
func (c *driverConn) Close() error {
var err errList
for _, s := range c.stmts {
stmt := s.(*driverStmt)
err.append(stmt.conn.s.DropPreparedStmt(stmt.stmtID))
}
c.driver.lock()
defer c.driver.unlock()
return err.error()
}
// Begin starts and returns a new transaction.
func (c *driverConn) Begin() (driver.Tx, error) {
if c.s == nil {
return nil, errors.Errorf("Need init first")
}
if _, err := c.s.Execute(txBeginSQL); err != nil {
return nil, errors.Trace(err)
}
return c, nil
}
func (c *driverConn) Commit() error {
if c.s == nil {
return terror.CommitNotInTransaction
}
_, err := c.s.Execute(txCommitSQL)
if err != nil {
return errors.Trace(err)
}
err = c.s.FinishTxn(false)
return errors.Trace(err)
}
func (c *driverConn) Rollback() error {
if c.s == nil {
return terror.RollbackNotInTransaction
}
if _, err := c.s.Execute(txRollbackSQL); err != nil {
return errors.Trace(err)
}
return nil
}
// Execer is an optional interface that may be implemented by a Conn.
//
// If a Conn does not implement Execer, the sql package's DB.Exec will first
// prepare a query, execute the statement, and then close the statement.
//
// Exec may return driver.ErrSkip.
func (c *driverConn) Exec(query string, args []driver.Value) (driver.Result, error) {
return c.driverExec(query, args)
}
func (c *driverConn) getStmt(query string) (stmt driver.Stmt, err error) {
stmt, ok := c.stmts[query]
if !ok {
stmt, err = c.Prepare(query)
if err != nil {
return nil, errors.Trace(err)
}
}
return
}
func (c *driverConn) driverExec(query string, args []driver.Value) (driver.Result, error) {
if len(args) == 0 {
if _, err := c.s.Execute(query); err != nil {
return nil, errors.Trace(err)
}
r := &driverResult{}
r.lastInsertID, r.rowsAffected = int64(c.s.LastInsertID()), int64(c.s.AffectedRows())
return r, nil
}
stmt, err := c.getStmt(query)
if err != nil {
return nil, errors.Trace(err)
}
return stmt.Exec(args)
}
// Queryer is an optional interface that may be implemented by a Conn.
//
// If a Conn does not implement Queryer, the sql package's DB.Query will first
// prepare a query, execute the statement, and then close the statement.
//
// Query may return driver.ErrSkip.
func (c *driverConn) Query(query string, args []driver.Value) (driver.Rows, error) {
return c.driverQuery(query, args)
}
func (c *driverConn) driverQuery(query string, args []driver.Value) (driver.Rows, error) {
if len(args) == 0 {
rss, err := c.s.Execute(query)
if err != nil {
return nil, errors.Trace(err)
}
if len(rss) == 0 {
return nil, errors.Trace(errNoResult)
}
return &driverRows{params: c.params, rs: rss[0]}, nil
}
stmt, err := c.getStmt(query)
if err != nil {
return nil, errors.Trace(err)
}
return stmt.Query(args)
}
// driverResult is the result of a query execution.
type driverResult struct {
lastInsertID int64
rowsAffected int64
}
// LastInsertID returns the database's auto-generated ID after, for example, an
// INSERT into a table with primary key.
func (r *driverResult) LastInsertId() (int64, error) { // -golint
return r.lastInsertID, nil
}
// RowsAffected returns the number of rows affected by the query.
func (r *driverResult) RowsAffected() (int64, error) {
return r.rowsAffected, nil
}
// driverRows is an iterator over an executed query's results.
type driverRows struct {
rs ast.RecordSet
params *driverParams
}
// Columns returns the names of the columns. The number of columns of the
// result is inferred from the length of the slice. If a particular column
// name isn't known, an empty string should be returned for that entry.
func (r *driverRows) Columns() []string {
if r.rs == nil {
return []string{}
}
fs, _ := r.rs.Fields()
names := make([]string, len(fs))
for i, f := range fs {
names[i] = f.ColumnAsName.O
}
return names
}
// Close closes the rows iterator.
func (r *driverRows) Close() error {
if r.rs != nil {
return r.rs.Close()
}
return nil
}
// Next is called to populate the next row of data into the provided slice. The
// provided slice will be the same size as the Columns() are wide.
//
// The dest slice may be populated only with a driver Value type, but excluding
// string. All string values must be converted to []byte.
//
// Next should return io.EOF when there are no more rows.
func (r *driverRows) Next(dest []driver.Value) error {
if r.rs == nil {
return io.EOF
}
row, err := r.rs.Next()
if err != nil {
return errors.Trace(err)
}
if row == nil {
return io.EOF
}
if len(row.Data) != len(dest) {
return errors.Errorf("field count mismatch: got %d, need %d", len(row.Data), len(dest))
}
for i, xi := range row.Data {
switch xi.Kind() {
case types.KindNull:
dest[i] = nil
case types.KindInt64:
dest[i] = xi.GetInt64()
case types.KindUint64:
dest[i] = xi.GetUint64()
case types.KindFloat32:
dest[i] = xi.GetFloat32()
case types.KindFloat64:
dest[i] = xi.GetFloat64()
case types.KindString:
dest[i] = xi.GetString()
case types.KindBytes:
dest[i] = xi.GetBytes()
case types.KindMysqlBit:
dest[i] = xi.GetMysqlBit().ToString()
case types.KindMysqlDecimal:
dest[i] = xi.GetMysqlDecimal().String()
case types.KindMysqlDuration:
dest[i] = xi.GetMysqlDuration().String()
case types.KindMysqlEnum:
dest[i] = xi.GetMysqlEnum().String()
case types.KindMysqlHex:
dest[i] = xi.GetMysqlHex().ToString()
case types.KindMysqlSet:
dest[i] = xi.GetMysqlSet().String()
case types.KindMysqlTime:
t := xi.GetMysqlTime()
if !r.params.parseTime {
dest[i] = t.String()
} else {
dest[i] = t.Time
}
default:
return errors.Errorf("unable to handle type %T", xi.GetValue())
}
}
return nil
}
// driverStmt is a prepared statement. It is bound to a driverConn and not used
// by multiple goroutines concurrently.
type driverStmt struct {
conn *driverConn
query string
stmtID uint32
paramCount int
isQuery bool
}
// Close closes the statement.
//
// As of Go 1.1, a Stmt will not be closed if it's in use by any queries.
func (s *driverStmt) Close() error {
s.conn.s.DropPreparedStmt(s.stmtID)
delete(s.conn.stmts, s.query)
return nil
}
// NumInput returns the number of placeholder parameters.
//
// If NumInput returns >= 0, the sql package will sanity check argument counts
// from callers and return errors to the caller before the statement's Exec or
// Query methods are called.
//
// NumInput may also return -1, if the driver doesn't know its number of
// placeholders. In that case, the sql package will not sanity check Exec or
// Query argument counts.
func (s *driverStmt) NumInput() int {
return s.paramCount
}
// Exec executes a query that doesn't return rows, such as an INSERT or UPDATE.
func (s *driverStmt) Exec(args []driver.Value) (driver.Result, error) {
c := s.conn
_, err := c.s.ExecutePreparedStmt(s.stmtID, params(args)...)
if err != nil {
return nil, errors.Trace(err)
}
r := &driverResult{}
if s != nil {
r.lastInsertID, r.rowsAffected = int64(c.s.LastInsertID()), int64(c.s.AffectedRows())
}
return r, nil
}
// Exec executes a query that may return rows, such as a SELECT.
func (s *driverStmt) Query(args []driver.Value) (driver.Rows, error) {
c := s.conn
rs, err := c.s.ExecutePreparedStmt(s.stmtID, params(args)...)
if err != nil {
return nil, errors.Trace(err)
}
if rs == nil {
if s.isQuery {
return nil, errors.Trace(errNoResult)
}
// The statement is not a query.
return &driverRows{}, nil
}
return &driverRows{params: s.conn.params, rs: rs}, nil
}
func init() {
RegisterDriver()
}

130
vendor/github.com/pingcap/tidb/evaluator/builtin.go generated vendored Normal file
View file

@ -0,0 +1,130 @@
// Copyright 2013 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSES/QL-LICENSE file.
// 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 evaluator
import (
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/util/types"
)
// OldFunc is for a old builtin function.
type OldFunc struct {
// F is the specific calling function.
F func([]interface{}, context.Context) (interface{}, error)
// MinArgs is the minimal arguments needed,
MinArgs int
// MaxArgs is the maximal arguments needed, -1 for infinity.
MaxArgs int
// IsStatic shows whether this function can be called statically.
IsStatic bool
// IsAggregate represents whether this function is an aggregate function or not.
IsAggregate bool
}
// Func is for a builtin function.
type Func struct {
// F is the specific calling function.
F func([]types.Datum, context.Context) (types.Datum, error)
// MinArgs is the minimal arguments needed,
MinArgs int
// MaxArgs is the maximal arguments needed, -1 for infinity.
MaxArgs int
}
// OldFuncs holds all has old registered builtin functions.
var OldFuncs = map[string]OldFunc{
// control functions
"if": {builtinIf, 3, 3, true, false},
"ifnull": {builtinIfNull, 2, 2, true, false},
"nullif": {builtinNullIf, 2, 2, true, false},
// string functions
"replace": {builtinReplace, 3, 3, true, false},
"strcmp": {builtinStrcmp, 2, 2, true, false},
"convert": {builtinConvert, 2, 2, true, false},
"substring": {builtinSubstring, 2, 3, true, false},
"substring_index": {builtinSubstringIndex, 3, 3, true, false},
"locate": {builtinLocate, 2, 3, true, false},
"trim": {builtinTrim, 1, 3, true, false},
// information functions
"current_user": {builtinCurrentUser, 0, 0, false, false},
"database": {builtinDatabase, 0, 0, false, false},
"found_rows": {builtinFoundRows, 0, 0, false, false},
"user": {builtinUser, 0, 0, false, false},
"connection_id": {builtinConnectionID, 0, 0, true, false},
"version": {builtinVersion, 0, 0, true, false},
}
// Funcs holds all registered builtin functions.
var Funcs = map[string]Func{
// common functions
"coalesce": {builtinCoalesce, 1, -1},
// math functions
"abs": {builtinAbs, 1, 1},
"pow": {builtinPow, 2, 2},
"power": {builtinPow, 2, 2},
"rand": {builtinRand, 0, 1},
// time functions
"curdate": {builtinCurrentDate, 0, 0},
"current_date": {builtinCurrentDate, 0, 0},
"current_time": {builtinCurrentTime, 0, 1},
"current_timestamp": {builtinNow, 0, 1},
"curtime": {builtinCurrentTime, 0, 1},
"date": {builtinDate, 1, 1},
"day": {builtinDay, 1, 1},
"dayname": {builtinDayName, 1, 1},
"dayofmonth": {builtinDayOfMonth, 1, 1},
"dayofweek": {builtinDayOfWeek, 1, 1},
"dayofyear": {builtinDayOfYear, 1, 1},
"hour": {builtinHour, 1, 1},
"microsecond": {builtinMicroSecond, 1, 1},
"minute": {builtinMinute, 1, 1},
"month": {builtinMonth, 1, 1},
"now": {builtinNow, 0, 1},
"second": {builtinSecond, 1, 1},
"sysdate": {builtinSysDate, 0, 1},
"week": {builtinWeek, 1, 2},
"weekday": {builtinWeekDay, 1, 1},
"weekofyear": {builtinWeekOfYear, 1, 1},
"year": {builtinYear, 1, 1},
"yearweek": {builtinYearWeek, 1, 2},
"extract": {builtinExtract, 2, 2},
"date_arith": {builtinDateArith, 3, 3},
// string functions
"concat": {builtinConcat, 1, -1},
"concat_ws": {builtinConcatWS, 2, -1},
"left": {builtinLeft, 2, 2},
"length": {builtinLength, 1, 1},
"lower": {builtinLower, 1, 1},
"repeat": {builtinRepeat, 2, 2},
"upper": {builtinUpper, 1, 1},
}
// See: http://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function_coalesce
func builtinCoalesce(args []types.Datum, ctx context.Context) (d types.Datum, err error) {
for _, d = range args {
if d.Kind() != types.KindNull {
return d, nil
}
}
return d, nil
}

View file

@ -0,0 +1,76 @@
// 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 evaluator
import (
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/util/types"
)
// See https://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html#function_if
func builtinIf(args []interface{}, _ context.Context) (interface{}, error) {
// if(expr1, expr2, expr3)
// if expr1 is true, return expr2, otherwise, return expr3
v1 := args[0]
v2 := args[1]
v3 := args[2]
if v1 == nil {
return v3, nil
}
b, err := types.ToBool(v1)
if err != nil {
return nil, err
}
// TODO: check return type, must be numeric or string
if b == 1 {
return v2, nil
}
return v3, nil
}
// See https://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html#function_ifnull
func builtinIfNull(args []interface{}, _ context.Context) (interface{}, error) {
// ifnull(expr1, expr2)
// if expr1 is not null, return expr1, otherwise, return expr2
v1 := args[0]
v2 := args[1]
if v1 != nil {
return v1, nil
}
return v2, nil
}
// See https://dev.mysql.com/doc/refman/5.7/en/control-flow-functions.html#function_nullif
func builtinNullIf(args []interface{}, _ context.Context) (interface{}, error) {
// nullif(expr1, expr2)
// returns null if expr1 = expr2 is true, otherwise returns expr1
v1 := args[0]
v2 := args[1]
if v1 == nil || v2 == nil {
return v1, nil
}
if n, err := types.Compare(v1, v2); err != nil || n == 0 {
return nil, err
}
return v1, nil
}

View file

@ -0,0 +1,78 @@
// Copyright 2013 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSES/QL-LICENSE file.
// 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 evaluator
import (
"github.com/juju/errors"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/mysql"
"github.com/pingcap/tidb/sessionctx/db"
"github.com/pingcap/tidb/sessionctx/variable"
)
// See: https://dev.mysql.com/doc/refman/5.7/en/information-functions.html
func builtinDatabase(args []interface{}, ctx context.Context) (v interface{}, err error) {
d := db.GetCurrentSchema(ctx)
if d == "" {
return nil, nil
}
return d, nil
}
func builtinFoundRows(arg []interface{}, ctx context.Context) (interface{}, error) {
data := variable.GetSessionVars(ctx)
if data == nil {
return nil, errors.Errorf("Missing session variable when evalue builtin")
}
return data.FoundRows, nil
}
// See: https://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_current-user
// TODO: The value of CURRENT_USER() can differ from the value of USER(). We will finish this after we support grant tables.
func builtinCurrentUser(args []interface{}, ctx context.Context) (v interface{}, err error) {
data := variable.GetSessionVars(ctx)
if data == nil {
return nil, errors.Errorf("Missing session variable when evalue builtin")
}
return data.User, nil
}
func builtinUser(args []interface{}, ctx context.Context) (v interface{}, err error) {
data := variable.GetSessionVars(ctx)
if data == nil {
return nil, errors.Errorf("Missing session variable when evalue builtin")
}
return data.User, nil
}
func builtinConnectionID(args []interface{}, ctx context.Context) (v interface{}, err error) {
data := variable.GetSessionVars(ctx)
if data == nil {
return nil, errors.Errorf("Missing session variable when evalue builtin")
}
return data.ConnectionID, nil
}
func builtinVersion(args []interface{}, ctx context.Context) (v interface{}, err error) {
return mysql.ServerVersion, nil
}

View file

@ -0,0 +1,83 @@
// Copyright 2013 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSES/QL-LICENSE file.
// 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 evaluator
import (
"math"
"math/rand"
"github.com/juju/errors"
"github.com/pingcap/tidb/context"
"github.com/pingcap/tidb/util/types"
)
// see https://dev.mysql.com/doc/refman/5.7/en/mathematical-functions.html
func builtinAbs(args []types.Datum, _ context.Context) (d types.Datum, err error) {
d = args[0]
switch d.Kind() {
case types.KindNull:
return d, nil
case types.KindUint64:
return d, nil
case types.KindInt64:
iv := d.GetInt64()
if iv >= 0 {
d.SetInt64(iv)
return d, nil
}
d.SetInt64(-iv)
return d, nil
default:
// we will try to convert other types to float
// TODO: if time has no precision, it will be a integer
f, err := d.ToFloat64()
d.SetFloat64(math.Abs(f))
return d, errors.Trace(err)
}
}
func builtinRand(args []types.Datum, _ context.Context) (d types.Datum, err error) {
if len(args) == 1 && args[0].Kind() != types.KindNull {
seed, err := args[0].ToInt64()
if err != nil {
d.SetNull()
return d, errors.Trace(err)
}
rand.Seed(seed)
}
d.SetFloat64(rand.Float64())
return d, nil
}
func builtinPow(args []types.Datum, _ context.Context) (d types.Datum, err error) {
x, err := args[0].ToFloat64()
if err != nil {
d.SetNull()
return d, errors.Trace(err)
}
y, err := args[1].ToFloat64()
if err != nil {
d.SetNull()
return d, errors.Trace(err)
}
d.SetFloat64(math.Pow(x, y))
return d, nil
}

Some files were not shown because too many files have changed in this diff Show more