sql

package
v0.0.0-...-c8a8ecc Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2015 License: Apache-2.0 Imports: 34 Imported by: 0

Documentation

Overview

Package sql provides the user-facing API for access to a Cockroach datastore. As the name suggests, the API is based around SQL, the same SQL you find in traditional RDMBS systems like Oracle, MySQL or Postgres. The core Cockroach system implements a distributed, transactional, monolithic sorted key-value map. The sql package builds on top of this core system adding parsing, query planning and query execution as well as defining the privilege model.

Databases and Tables

The two primary objects are databases and tables. A database is a namespace which holds a series of tables. Conceptually, a database can be viewed like a directory in a filesystem plus some additional metadata (privileges). A table is like a file on steroids: containing a structured layout of rows and columns along with secondary indexes.

Like a directory, a database has a name and metadata. The metadata is defined by the DatabaseDescriptor:

message DatabaseDescriptor {
  optional string name;
  optional uint32 id;
  optional PrivilegeDescriptor privileges;
}

Similarly, tables have a TableDescriptor:

message TableDescriptor {
  optional string name;
  optional uint32 id;
  repeated ColumnDescriptor columns;
  optional IndexDescriptor primary_index;
  repeated IndexDescriptor indexes;
  optional PrivilegeDescriptor privileges;
}

Both the database ID and the table ID are allocate from the same "ID space" and IDs are never reused.

The namespace in which databases and tables exist contains only two levels: the root level contains databases and the database level contains tables. The "system.namespace" and "system.descriptor" tables implement the mapping from database/table name to ID and from ID to descriptor:

CREATE TABLE system.namespace (
  "parentID" INT,
  "name"     CHAR,
  "id"       INT,
  PRIMARY KEY (parentID, name)
);

CREATE TABLE system.descriptor (
  "id"         INT PRIMARY KEY,
  "descriptor" BLOB
);

The reserved ID of 0 is used for the "root" of the namespace in which the databases reside. In order to lookup the ID of a database given its name, the system effectively does a query like:

SELECT id FROM system.namespace WHERE parentID = 0 AND name = <database-name>

And given a database/table ID, the system looks up the descriptor using a query like:

SELECT descriptor FROM system.descriptor WHERE id = <ID>

Primary Key Addressing

All of the SQL data stored in tables is mapped down to keys and values. This mapping is referred to as key addressing. All tables have a primary key, whether explicitly listed in the schema or automatically generated. Note that a primary key is unrelated to the core Cockroach key-value functionality and is instead referring to the primary key for a SQL table.

The primary key consists of one or more non-NULL columns from the table. For a given row of the table, the columns for the primary key are encoded into a single string using the routines in util/encoding. These routines allow for the encoding of NULL values, integers, floating pointer numbers and strings in such a way that lexicographic ordering of the encoded strings corresponds to the same ordering of the unencoded data. Using "system.namespace" as an example, the primary key columns would be encoded as:

/parentID/name

[Note that "/" is being used to disambiguate the components of the key. The actual encodings do not use "/"].

Before being stored in the monolothic key-value space, the encoded primary key columns are prefixed with the table ID and an ID indicating that the key corresponds to the primary index:

/TableID/PrimaryIndexID/parentID/name

The column data associated with a row in a table is stored within the primary index which is the index associated with the primary key. Every column has a unique ID (that is local to the table). The value for a column is stored at the key:

/TableID/PrimaryIndexID/parentID/name/ColumnID -> Value

A column containing a NULL value is not stored in the monolithic map. In order to detect rows which only contain NULL values in non-primary key columns, every row has a sentinel key indicating its existence. The sentinel key is simply the primary index key:

/TableID/PrimaryIndexID/parentID/name -> NULL

As an optimization, columns that are part of the primary key are not stored separately as their data can be decoded from the sentinel value.

Secondary Indexes

Despite not being a formal part of SQL, secondary indexes are one of its most powerful features. Secondary indexes are a level of indirection that allow quick lookup of a row using something other than the primary key. As an example, we can imagine creating a secondary index on the "system.namespace" table:

CREATE INDEX name ON system.namespace (name);

This would create a "name" index composed solely of the "name" column. The key addressing for this non-unique index looks like:

/TableId/SecondaryIndexID/name/parentID -> NULL

Notice that while the index is on "name", the key contains both "name" and "parentID". This is done to ensure that each row for a table has a unique key for the non-unique index. In general, for a non-unique index we encoded the index's columns followed by any primary key columns that have not already been mentioned. This effectively transforms any non-unique index into a unique index.

Let's suppose that we had instead defined the index as:

CREATE UNIQUE INDEX name ON system.namespace (name, id);

The key addressing for a unique index looks like:

/TableID/SecondaryID/name/ID -> /parentID

Unique index keys are defined like this so that a conditional put operation can fail if that key already exists for another row, thereby enforcing the uniqueness constraint. The value for a unique index is composed of any primary key columns that are not part of the index ("parentID" in this example).

Query Planning and Execution

Query planning is the system which takes a parsed SQL statement (described by an abstract syntax tree) and creates an execution plan which is itself a tree consisting of a set of scan, join, group, sort and projection operations. For the bulk of SQL statements, query planning is straightforward: the complexity lies in SELECT.

At one end of the performance spectrum, an implementation of SELECT can be straightforward: do a full scan of the (joined) tables in the FROM clause, filter rows based on the WHERE clause, group the resulting rows based on the GROUP BY clause, filter those rows using the HAVING clause, sort using the ORDER BY clause. There are a number of steps, but they all have well defined semantics and are mostly just an exercise in software engineering: retrieve the rows as quickly as possible and then send them through the pipeline of filtering, grouping, filtering and sorting.

At the other end of the performance spectrum, query planners attempt to take advantage of secondary indexes to limit the data retrieved, make joining of data between two tables easier and faster and to avoid the need to sort data by retrieving it in a sorted or partially sorted form. The details of how we implement this are in flux and will continue to be in flux for the forseeable future. This section is intended to provide a high-level overview of a few of the techniques involved.

After parsing a SELECT query, the query planner performs semantic analysis to verify the queries correctness and to resolve names within the query to actual objects within the system. Let's consider the query:

SELECT id FROM system.namespace WHERE parentID = 0 AND name = 'test'

This query would look up the ID of the database named "test". The query planner needs to resolve the "system.namespace" qualified name in the FROM clause to the appropriate TableDescriptor. It also needs to resolve the "id", "parentID" and "name" column references to the appropriate column descriptions with the "system.namespace" TableDescriptor. Lastly, as part of semantic analysis, the query planner verifies that the expressions in the select targets and the WHERE clause are valid (e.g. the WHERE clause evaluates to a boolean).

From that starting point, the query planner then analyzes the GROUP BY and ORDER BY clauses, adding "hidden" targets for expressions used in those clauses that are not explicit targets of the query. In our example without a GROUP BY or ORDER BY clause we move straight to the next step: index selection. Index selection is the stage where the query planner selects the best index to scan and selects the start and end keys to use for scanning the index. Depending on the query, the query planner might even select multiple ranges to scan from an index or multiple ranges from different indexes.

How does the query planner decide which index to use and which range of the index to scan? We currently use a restricted form of value propagation in oder to determine the range of possible values for columns referenced in the WHERE clause. Using this range information, each index is examined to determine if it is a potential candidate and ranked according to its specificity. In addition to ranking indexes by the column value range information, they are ranked by how well they match the sorting required by the ORDER BY clause. Back to the example above, the range information would determine that:

parentID >= 0 AND parentID <= 0 AND name >= 'test' and name <= 'test

Notice that each column has a start and end value associated with it. Since there is only a single index on the "system.namespace" table, it is always selected. The start key is computed using the range information as:

/system.descriptor/primary/0/test

The end key is computed as:

/system.descriptor/primary/0/tesu

The "tesu" suffix is not a typo: the end key is computed as the "prefix end key" for the key "/TableID/PrimaryIndexId/0/test". This is done by incrementing the final byte of the key such that "t" becomes "u".

Our example query thus only scans two key-value pairs:

/system.descriptor/primary/0/test    -> NULL
/system.descriptor/primary/0/test/id -> <ID>

API

  TODO(pmattis): Describe sql/driver.{Request,Response}?

	Package sql is a generated protocol buffer package.

	It is generated from these files:
		cockroach/sql/privilege.proto
		cockroach/sql/session.proto
		cockroach/sql/structured.proto

	It has these top-level messages:
		UserPrivileges
		PrivilegeDescriptor
		Session
		ColumnType
		ColumnDescriptor
		IndexDescriptor
		TableDescriptor
		DatabaseDescriptor
		Descriptor

Index

Constants

View Source
const (
	// PrimaryKeyIndexName is the name of the index for the primary key.
	PrimaryKeyIndexName = "primary"
)

Variables

View Source
var (
	ErrInvalidLengthPrivilege = fmt.Errorf("proto: negative length found during unmarshaling")
	ErrIntOverflowPrivilege   = fmt.Errorf("proto: integer overflow")
)
View Source
var (
	ErrInvalidLengthSession = fmt.Errorf("proto: negative length found during unmarshaling")
	ErrIntOverflowSession   = fmt.Errorf("proto: integer overflow")
)
View Source
var (
	ErrInvalidLengthStructured = fmt.Errorf("proto: negative length found during unmarshaling")
	ErrIntOverflowStructured   = fmt.Errorf("proto: integer overflow")
)
View Source
var (
	// SystemDB is the descriptor for the system database.
	SystemDB = DatabaseDescriptor{
		Name: "system",
		ID:   keys.SystemDatabaseID,

		Privileges: NewPrivilegeDescriptor(security.RootUser,
			SystemAllowedPrivileges[keys.SystemDatabaseID]),
	}

	// NamespaceTable is the descriptor for the namespace table.
	NamespaceTable = createSystemTable(keys.NamespaceTableID, namespaceTableSchema)

	// DescriptorTable is the descriptor for the descriptor table.
	DescriptorTable = createSystemTable(keys.DescriptorTableID, descriptorTableSchema)

	// LeaseTable is the descriptor for the lease table.
	LeaseTable = createSystemTable(keys.LeaseTableID, leaseTableSchema)

	// UsersTable is the descriptor for the users table.
	UsersTable = createSystemTable(keys.UsersTableID, usersTableSchema)

	// ZonesTable is the descriptor for the zones table.
	ZonesTable = createSystemTable(keys.ZonesTableID, zonesTableSchema)

	// SystemAllowedPrivileges describes the privileges allowed for each
	// system object. No user may have more than those privileges, and
	// the root user must have exactly those privileges.
	// CREATE|DROP|ALL should always be denied.
	SystemAllowedPrivileges = map[ID]privilege.List{
		keys.SystemDatabaseID:  privilege.ReadData,
		keys.NamespaceTableID:  privilege.ReadData,
		keys.DescriptorTableID: privilege.ReadData,
		keys.LeaseTableID:      privilege.ReadWriteData,
		keys.UsersTableID:      privilege.ReadWriteData,
		keys.ZonesTableID:      privilege.ReadWriteData,
	}

	// NumUsedSystemIDs is only used in tests that need to know the
	// number of system objects created at initialization.
	// It gets automatically set to "number of created system tables"
	// + 1 (for system database).
	NumUsedSystemIDs = 1
)
View Source
var ColumnType_Kind_name = map[int32]string{
	0: "BOOL",
	1: "INT",
	2: "FLOAT",
	3: "DECIMAL",
	4: "DATE",
	5: "TIMESTAMP",
	6: "INTERVAL",
	7: "STRING",
	8: "BYTES",
}
View Source
var ColumnType_Kind_value = map[string]int32{
	"BOOL":      0,
	"INT":       1,
	"FLOAT":     2,
	"DECIMAL":   3,
	"DATE":      4,
	"TIMESTAMP": 5,
	"INTERVAL":  6,
	"STRING":    7,
	"BYTES":     8,
}

Functions

func GetInitialSystemValues

func GetInitialSystemValues() []roachpb.KeyValue

GetInitialSystemValues returns a list of key/value pairs. They are written at cluster bootstrap time (see storage/node.go:BootstrapCLuster).

func GetZoneConfig

func GetZoneConfig(cfg config.SystemConfig, id uint32) (*config.ZoneConfig, error)

GetZoneConfig returns the zone config for the object with 'id'.

func IsSystemID

func IsSystemID(id ID) bool

IsSystemID returns true if this ID is reserved for system objects.

func MakeColumnKey

func MakeColumnKey(colID ColumnID, primaryKey []byte) roachpb.Key

MakeColumnKey returns the key for the column in the given row.

func MakeDescMetadataKey

func MakeDescMetadataKey(descID ID) roachpb.Key

MakeDescMetadataKey returns the key for the descriptor.

func MakeIndexKeyPrefix

func MakeIndexKeyPrefix(tableID ID, indexID IndexID) []byte

MakeIndexKeyPrefix returns the key prefix used for the index's data.

func MakeNameMetadataKey

func MakeNameMetadataKey(parentID ID, name string) roachpb.Key

MakeNameMetadataKey returns the key for the name. Pass name == "" in order to generate the prefix key to use to scan over all of the names for the specified parentID.

func MakeZoneKey

func MakeZoneKey(id ID) roachpb.Key

MakeZoneKey returns the key for 'id's entry in the system.zones table.

Types

type ColumnDescriptor

type ColumnDescriptor struct {
	Name     string     `protobuf:"bytes,1,opt,name=name" json:"name"`
	ID       ColumnID   `protobuf:"varint,2,opt,name=id,casttype=ColumnID" json:"id"`
	Type     ColumnType `protobuf:"bytes,3,opt,name=type" json:"type"`
	Nullable bool       `protobuf:"varint,4,opt,name=nullable" json:"nullable"`
	// Default expression to use to populate the column on insert if no
	// value is provided.
	DefaultExpr *string `protobuf:"bytes,5,opt,name=default_expr" json:"default_expr,omitempty"`
}

func (*ColumnDescriptor) Marshal

func (m *ColumnDescriptor) Marshal() (data []byte, err error)

func (*ColumnDescriptor) MarshalTo

func (m *ColumnDescriptor) MarshalTo(data []byte) (int, error)

func (*ColumnDescriptor) ProtoMessage

func (*ColumnDescriptor) ProtoMessage()

func (*ColumnDescriptor) Reset

func (m *ColumnDescriptor) Reset()

func (*ColumnDescriptor) Size

func (m *ColumnDescriptor) Size() (n int)

func (*ColumnDescriptor) String

func (m *ColumnDescriptor) String() string

func (*ColumnDescriptor) Unmarshal

func (m *ColumnDescriptor) Unmarshal(data []byte) error

type ColumnID

type ColumnID uint32

ColumnID is a custom type for ColumnDescriptor IDs.

type ColumnType

type ColumnType struct {
	Kind ColumnType_Kind `protobuf:"varint,1,opt,name=kind,enum=cockroach.sql.ColumnType_Kind" json:"kind"`
	// BIT, INT, FLOAT, DECIMAL, CHAR and BINARY
	Width int32 `protobuf:"varint,2,opt,name=width" json:"width"`
	// FLOAT and DECIMAL.
	Precision int32 `protobuf:"varint,3,opt,name=precision" json:"precision"`
}

func (*ColumnType) Marshal

func (m *ColumnType) Marshal() (data []byte, err error)

func (*ColumnType) MarshalTo

func (m *ColumnType) MarshalTo(data []byte) (int, error)

func (*ColumnType) ProtoMessage

func (*ColumnType) ProtoMessage()

func (*ColumnType) Reset

func (m *ColumnType) Reset()

func (*ColumnType) SQLString

func (c *ColumnType) SQLString() string

SQLString returns the SQL string corresponding to the type.

func (*ColumnType) Size

func (m *ColumnType) Size() (n int)

func (*ColumnType) String

func (m *ColumnType) String() string

func (*ColumnType) Unmarshal

func (m *ColumnType) Unmarshal(data []byte) error

type ColumnType_Kind

type ColumnType_Kind int32

These mirror the types supported by the sql/parser. See sql/parser/types.go.

const (
	ColumnType_BOOL      ColumnType_Kind = 0
	ColumnType_INT       ColumnType_Kind = 1
	ColumnType_FLOAT     ColumnType_Kind = 2
	ColumnType_DECIMAL   ColumnType_Kind = 3
	ColumnType_DATE      ColumnType_Kind = 4
	ColumnType_TIMESTAMP ColumnType_Kind = 5
	ColumnType_INTERVAL  ColumnType_Kind = 6
	ColumnType_STRING    ColumnType_Kind = 7
	ColumnType_BYTES     ColumnType_Kind = 8
)

func (ColumnType_Kind) Enum

func (x ColumnType_Kind) Enum() *ColumnType_Kind

func (ColumnType_Kind) String

func (x ColumnType_Kind) String() string

func (*ColumnType_Kind) UnmarshalJSON

func (x *ColumnType_Kind) UnmarshalJSON(data []byte) error

type DatabaseDescriptor

type DatabaseDescriptor struct {
	Name       string               `protobuf:"bytes,1,opt,name=name" json:"name"`
	ID         ID                   `protobuf:"varint,2,opt,name=id,casttype=ID" json:"id"`
	Privileges *PrivilegeDescriptor `protobuf:"bytes,3,opt,name=privileges" json:"privileges,omitempty"`
}

DatabaseDescriptor represents a namespace (aka database) and is stored in a structured metadata key. The DatabaseDescriptor has a globally-unique ID shared with the TableDescriptor ID. Permissions are applied to all tables in the namespace.

func (*DatabaseDescriptor) GetID

func (m *DatabaseDescriptor) GetID() ID

func (*DatabaseDescriptor) GetName

func (m *DatabaseDescriptor) GetName() string

func (*DatabaseDescriptor) GetPrivileges

func (m *DatabaseDescriptor) GetPrivileges() *PrivilegeDescriptor

func (*DatabaseDescriptor) Marshal

func (m *DatabaseDescriptor) Marshal() (data []byte, err error)

func (*DatabaseDescriptor) MarshalTo

func (m *DatabaseDescriptor) MarshalTo(data []byte) (int, error)

func (*DatabaseDescriptor) ProtoMessage

func (*DatabaseDescriptor) ProtoMessage()

func (*DatabaseDescriptor) Reset

func (m *DatabaseDescriptor) Reset()

func (*DatabaseDescriptor) SetID

func (desc *DatabaseDescriptor) SetID(id ID)

SetID implements the descriptorProto interface.

func (*DatabaseDescriptor) SetName

func (desc *DatabaseDescriptor) SetName(name string)

SetName implements the descriptorProto interface.

func (*DatabaseDescriptor) Size

func (m *DatabaseDescriptor) Size() (n int)

func (*DatabaseDescriptor) String

func (m *DatabaseDescriptor) String() string

func (*DatabaseDescriptor) TypeName

func (desc *DatabaseDescriptor) TypeName() string

TypeName returns the plain type of this descriptor.

func (*DatabaseDescriptor) Unmarshal

func (m *DatabaseDescriptor) Unmarshal(data []byte) error

func (*DatabaseDescriptor) Validate

func (desc *DatabaseDescriptor) Validate() error

Validate validates that the database descriptor is well formed. Checks include validate the database name, and verifying that there is at least one read and write user.

type Descriptor

type Descriptor struct {
	// Types that are valid to be assigned to Union:
	//	*Descriptor_Table
	//	*Descriptor_Database
	Union isDescriptor_Union `protobuf_oneof:"union"`
}

Descriptor is a union type holding either a table or database descriptor.

func (*Descriptor) GetDatabase

func (m *Descriptor) GetDatabase() *DatabaseDescriptor

func (*Descriptor) GetTable

func (m *Descriptor) GetTable() *TableDescriptor

func (*Descriptor) GetUnion

func (m *Descriptor) GetUnion() isDescriptor_Union

func (*Descriptor) Marshal

func (m *Descriptor) Marshal() (data []byte, err error)

func (*Descriptor) MarshalTo

func (m *Descriptor) MarshalTo(data []byte) (int, error)

func (*Descriptor) ProtoMessage

func (*Descriptor) ProtoMessage()

func (*Descriptor) Reset

func (m *Descriptor) Reset()

func (*Descriptor) Size

func (m *Descriptor) Size() (n int)

func (*Descriptor) String

func (m *Descriptor) String() string

func (*Descriptor) Unmarshal

func (m *Descriptor) Unmarshal(data []byte) error

func (*Descriptor) XXX_OneofFuncs

func (*Descriptor) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{})

XXX_OneofFuncs is for the internal use of the proto package.

type Descriptor_Database

type Descriptor_Database struct {
	Database *DatabaseDescriptor `protobuf:"bytes,2,opt,name=database,oneof"`
}

func (*Descriptor_Database) MarshalTo

func (m *Descriptor_Database) MarshalTo(data []byte) (int, error)

func (*Descriptor_Database) Size

func (m *Descriptor_Database) Size() (n int)

type Descriptor_Table

type Descriptor_Table struct {
	Table *TableDescriptor `protobuf:"bytes,1,opt,name=table,oneof"`
}

func (*Descriptor_Table) MarshalTo

func (m *Descriptor_Table) MarshalTo(data []byte) (int, error)

func (*Descriptor_Table) Size

func (m *Descriptor_Table) Size() (n int)

type Executor

type Executor struct {
	// contains filtered or unexported fields
}

An Executor executes SQL statements.

func (*Executor) Execute

func (e *Executor) Execute(args driver.Request) (driver.Response, int, error)

Execute the statement(s) in the given request and return a response. On error, the returned integer is an HTTP error code.

func (*Executor) SetNodeID

func (e *Executor) SetNodeID(nodeID roachpb.NodeID)

SetNodeID sets the node ID for the SQL server. This method must be called before actually using the Executor.

type ID

type ID uint32

ID is a custom type for {Database,Table}Descriptor IDs.

type IndexDescriptor

type IndexDescriptor struct {
	Name   string  `protobuf:"bytes,1,opt,name=name" json:"name"`
	ID     IndexID `protobuf:"varint,2,opt,name=id,casttype=IndexID" json:"id"`
	Unique bool    `protobuf:"varint,3,opt,name=unique" json:"unique"`
	// An ordered list of column names of which the index is comprised. This list
	// parallels the column_ids list. If duplicating the storage of the column
	// names here proves to be prohibitive, we could clear this field before
	// saving and reconstruct it after loading.
	ColumnNames []string `protobuf:"bytes,4,rep,name=column_names" json:"column_names,omitempty"`
	// An ordered list of column names which the index stores in
	// addition to the columns which are explicitly part of the index.
	StoreColumnNames []string `protobuf:"bytes,5,rep,name=store_column_names" json:"store_column_names,omitempty"`
	// An ordered list of column ids of which the index is comprised. This list
	// parallels the column_names list.
	ColumnIDs []ColumnID `protobuf:"varint,6,rep,name=column_ids,casttype=ColumnID" json:"column_ids,omitempty"`
	// An ordered list of implicit column ids associated with the index. For
	// non-unique indexes, these columns will be appended to the key. For unique
	// indexes these columns will be stored in the value. The extra column IDs is
	// computed as PrimaryIndex.column_ids - column_ids. For the primary index
	// the list will be empty.
	ImplicitColumnIDs []ColumnID `protobuf:"varint,7,rep,name=implicit_column_ids,casttype=ColumnID" json:"implicit_column_ids,omitempty"`
}

func (*IndexDescriptor) Marshal

func (m *IndexDescriptor) Marshal() (data []byte, err error)

func (*IndexDescriptor) MarshalTo

func (m *IndexDescriptor) MarshalTo(data []byte) (int, error)

func (*IndexDescriptor) ProtoMessage

func (*IndexDescriptor) ProtoMessage()

func (*IndexDescriptor) Reset

func (m *IndexDescriptor) Reset()

func (*IndexDescriptor) Size

func (m *IndexDescriptor) Size() (n int)

func (*IndexDescriptor) String

func (m *IndexDescriptor) String() string

func (*IndexDescriptor) Unmarshal

func (m *IndexDescriptor) Unmarshal(data []byte) error

type IndexID

type IndexID uint32

IndexID is a custom type for IndexDescriptor IDs.

type LeaseManager

type LeaseManager struct {
	LeaseStore
	// contains filtered or unexported fields
}

LeaseManager manages acquiring and releasing per-table leases. Exported only for testing.

func NewLeaseManager

func NewLeaseManager(nodeID uint32, db client.DB, clock *hlc.Clock) *LeaseManager

NewLeaseManager creates a new LeaseManager.

func (*LeaseManager) Acquire

func (m *LeaseManager) Acquire(txn *client.Txn, tableID ID, version uint32) (*LeaseState, error)

Acquire acquires a read lease for the specified table ID. If version is non-zero the lease is grabbed for the specified version. Otherwise it is grabbed for the most recent version of the descriptor that the lease manager knows about.

func (*LeaseManager) Release

func (m *LeaseManager) Release(lease *LeaseState) error

Release releases a previously acquired read lease.

type LeaseState

type LeaseState struct {
	TableDescriptor
	// contains filtered or unexported fields
}

LeaseState holds the state for a lease. Exported only for testing.

func (*LeaseState) Expiration

func (s *LeaseState) Expiration() time.Time

Expiration returns the expiration time of the lease.

func (*LeaseState) Refcount

func (s *LeaseState) Refcount() int

Refcount returns the reference count of the lease.

func (*LeaseState) String

func (s *LeaseState) String() string

type LeaseStore

type LeaseStore struct {
	// contains filtered or unexported fields
}

LeaseStore implements the operations for acquiring and releasing leases and publishing a new version of a descriptor. Exported only for testing.

func (LeaseStore) Acquire

func (s LeaseStore) Acquire(txn *client.Txn, tableID ID, minVersion uint32) (*LeaseState, error)

Acquire a lease on the most recent version of a table descriptor.

func (LeaseStore) Publish

func (s LeaseStore) Publish(tableID ID, update func(*TableDescriptor) error) error

Publish a new version of a table descriptor. The update closure may be called multiple times if retries occur: make sure it does not have side effects.

func (LeaseStore) Release

func (s LeaseStore) Release(lease *LeaseState) error

Release a previously acquired table descriptor lease.

type PrivilegeDescriptor

type PrivilegeDescriptor struct {
	Users []*UserPrivileges `protobuf:"bytes,1,rep,name=users" json:"users,omitempty"`
}

PrivilegeDescriptor describes a list of users and attached privileges. The list should be sorted by user for fast access.

func NewDefaultPrivilegeDescriptor

func NewDefaultPrivilegeDescriptor() *PrivilegeDescriptor

NewDefaultPrivilegeDescriptor returns a privilege descriptor with ALL privileges for the root user.

func NewPrivilegeDescriptor

func NewPrivilegeDescriptor(user string, priv privilege.List) *PrivilegeDescriptor

NewPrivilegeDescriptor returns a privilege descriptor for the given user with the specified list of privileges.

func (*PrivilegeDescriptor) CheckPrivilege

func (p *PrivilegeDescriptor) CheckPrivilege(user string, priv privilege.Kind) bool

CheckPrivilege returns true if 'user' has 'privilege' on this descriptor.

func (*PrivilegeDescriptor) Grant

func (p *PrivilegeDescriptor) Grant(user string, privList privilege.List)

Grant adds new privileges to this descriptor for a given list of users. TODO(marc): if all privileges other than ALL are set, should we collapse them into ALL?

func (*PrivilegeDescriptor) Marshal

func (m *PrivilegeDescriptor) Marshal() (data []byte, err error)

func (*PrivilegeDescriptor) MarshalTo

func (m *PrivilegeDescriptor) MarshalTo(data []byte) (int, error)

func (*PrivilegeDescriptor) ProtoMessage

func (*PrivilegeDescriptor) ProtoMessage()

func (*PrivilegeDescriptor) Reset

func (m *PrivilegeDescriptor) Reset()

func (*PrivilegeDescriptor) Revoke

func (p *PrivilegeDescriptor) Revoke(user string, privList privilege.List)

Revoke removes privileges from this descriptor for a given list of users.

func (*PrivilegeDescriptor) Show

Show returns the list of {username, privileges} sorted by username. 'privileges' is a string of comma-separated sorted privilege names.

func (*PrivilegeDescriptor) Size

func (m *PrivilegeDescriptor) Size() (n int)

func (*PrivilegeDescriptor) String

func (m *PrivilegeDescriptor) String() string

func (*PrivilegeDescriptor) Unmarshal

func (m *PrivilegeDescriptor) Unmarshal(data []byte) error

func (*PrivilegeDescriptor) Validate

func (p *PrivilegeDescriptor) Validate(id ID) error

Validate is called when writing a database or table descriptor. It takes the descriptor ID which is used to determine if it belongs to a system descriptor, in which case the maximum set of allowed privileges is looked up and applied.

type Server

type Server struct {
	*Executor
	// contains filtered or unexported fields
}

An Server provides both an HTTP and RPC server endpoint serving the SQL API. The HTTP endpoint accepts either JSON or serialized protobuf content types.

func MakeServer

func MakeServer(ctx *base.Context, db client.DB, gossip *gossip.Gossip, clock *hlc.Clock) Server

MakeServer creates a Server.

func (Server) RegisterRPC

func (s Server) RegisterRPC(rpcServer *rpc.Server) error

RegisterRPC registers the SQL RPC endpoint.

func (Server) ServeHTTP

func (s Server) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP serves the SQL API by treating the request URL path as the method, the request body as the arguments, and sets the response body as the method reply. The request body is unmarshalled into arguments based on the Content-Type request header. Protobuf and JSON-encoded requests are supported. The response body is encoded according to the request's Accept header, or if not present, in the same format as the request's incoming Content-Type header.

type Session

type Session struct {
	Database string `protobuf:"bytes,1,opt,name=database" json:"database"`
	Syntax   int32  `protobuf:"varint,2,opt,name=syntax" json:"syntax"`
	// Open transaction.
	Txn *Session_Transaction `protobuf:"bytes,3,opt,name=txn" json:"txn,omitempty"`
	// Indicates that the above transaction is mutating keys in the
	// SystemDB span.
	MutatesSystemDB bool `protobuf:"varint,4,opt,name=mutates_system_db" json:"mutates_system_db"`
	// Types that are valid to be assigned to Timezone:
	//	*Session_Location
	//	*Session_Offset
	Timezone isSession_Timezone `protobuf_oneof:"timezone"`
}

func (*Session) GetLocation

func (m *Session) GetLocation() string

func (*Session) GetOffset

func (m *Session) GetOffset() int64

func (*Session) GetTimezone

func (m *Session) GetTimezone() isSession_Timezone

func (*Session) Marshal

func (m *Session) Marshal() (data []byte, err error)

func (*Session) MarshalTo

func (m *Session) MarshalTo(data []byte) (int, error)

func (*Session) ProtoMessage

func (*Session) ProtoMessage()

func (*Session) Reset

func (m *Session) Reset()

func (*Session) Size

func (m *Session) Size() (n int)

func (*Session) String

func (m *Session) String() string

func (*Session) Unmarshal

func (m *Session) Unmarshal(data []byte) error

func (*Session) XXX_OneofFuncs

func (*Session) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{})

XXX_OneofFuncs is for the internal use of the proto package.

type Session_Location

type Session_Location struct {
	Location string `protobuf:"bytes,5,opt,name=location,oneof"`
}

func (*Session_Location) MarshalTo

func (m *Session_Location) MarshalTo(data []byte) (int, error)

func (*Session_Location) Size

func (m *Session_Location) Size() (n int)

type Session_Offset

type Session_Offset struct {
	Offset int64 `protobuf:"varint,6,opt,name=offset,oneof"`
}

func (*Session_Offset) MarshalTo

func (m *Session_Offset) MarshalTo(data []byte) (int, error)

func (*Session_Offset) Size

func (m *Session_Offset) Size() (n int)

type Session_Transaction

type Session_Transaction struct {
	Txn cockroach_roachpb1.Transaction `protobuf:"bytes,1,opt,name=txn" json:"txn"`
	// Timestamp to be used by SQL in the above transaction. Note: this is not the
	// transaction timestamp in roachpb.Transaction above.
	Timestamp cockroach_sql_driver.Datum_Timestamp `protobuf:"bytes,2,opt,name=timestamp" json:"timestamp"`
}

func (*Session_Transaction) Marshal

func (m *Session_Transaction) Marshal() (data []byte, err error)

func (*Session_Transaction) MarshalTo

func (m *Session_Transaction) MarshalTo(data []byte) (int, error)

func (*Session_Transaction) ProtoMessage

func (*Session_Transaction) ProtoMessage()

func (*Session_Transaction) Reset

func (m *Session_Transaction) Reset()

func (*Session_Transaction) Size

func (m *Session_Transaction) Size() (n int)

func (*Session_Transaction) String

func (m *Session_Transaction) String() string

func (*Session_Transaction) Unmarshal

func (m *Session_Transaction) Unmarshal(data []byte) error

type TableDescriptor

type TableDescriptor struct {
	Name string `protobuf:"bytes,1,opt,name=name" json:"name"`
	// The alias for the table. This is only used during query
	// processing and not stored persistently.
	Alias string `protobuf:"bytes,2,opt,name=alias" json:"alias"`
	ID    ID     `protobuf:"varint,3,opt,name=id,casttype=ID" json:"id"`
	// ID of the parent database.
	ParentID ID `protobuf:"varint,4,opt,name=parent_id,casttype=ID" json:"parent_id"`
	// Monotonically increasing version of the table descriptor.
	Version uint32 `protobuf:"varint,5,opt,name=version" json:"version"`
	// Last modification time of the table descriptor.
	ModificationTime cockroach_roachpb1.Timestamp `protobuf:"bytes,6,opt,name=modification_time" json:"modification_time"`
	Columns          []ColumnDescriptor           `protobuf:"bytes,7,rep,name=columns" json:"columns"`
	// next_column_id is used to ensure that deleted column ids are not reused.
	NextColumnID ColumnID        `protobuf:"varint,8,opt,name=next_column_id,casttype=ColumnID" json:"next_column_id"`
	PrimaryIndex IndexDescriptor `protobuf:"bytes,9,opt,name=primary_index" json:"primary_index"`
	// indexes are all the secondary indexes.
	Indexes []IndexDescriptor `protobuf:"bytes,10,rep,name=indexes" json:"indexes"`
	// next_index_id is used to ensure that deleted index ids are not reused.
	NextIndexID IndexID              `protobuf:"varint,11,opt,name=next_index_id,casttype=IndexID" json:"next_index_id"`
	Privileges  *PrivilegeDescriptor `protobuf:"bytes,12,opt,name=privileges" json:"privileges,omitempty"`
}

A TableDescriptor represents a table and is stored in a structured metadata key. The TableDescriptor has a globally-unique ID, while its member {Column,Index}Descriptors have locally-unique IDs.

func (*TableDescriptor) AddColumn

func (desc *TableDescriptor) AddColumn(col ColumnDescriptor)

AddColumn adds a column to the table.

func (*TableDescriptor) AddIndex

func (desc *TableDescriptor) AddIndex(idx IndexDescriptor, primary bool) error

AddIndex adds an index to the table.

func (*TableDescriptor) AllocateIDs

func (desc *TableDescriptor) AllocateIDs() error

AllocateIDs allocates column and index ids for any column or index which has an ID of 0.

func (*TableDescriptor) FindColumnByID

func (desc *TableDescriptor) FindColumnByID(id ColumnID) (*ColumnDescriptor, error)

FindColumnByID finds the column with specified ID.

func (*TableDescriptor) FindColumnByName

func (desc *TableDescriptor) FindColumnByName(name string) (int, error)

FindColumnByName finds the column with specified name.

func (*TableDescriptor) FindIndexByID

func (desc *TableDescriptor) FindIndexByID(id IndexID) (*IndexDescriptor, error)

FindIndexByID finds the index with specified ID.

func (*TableDescriptor) FindIndexByName

func (desc *TableDescriptor) FindIndexByName(name string) (int, error)

FindIndexByName finds the index with specified name.

func (*TableDescriptor) GetAlias

func (m *TableDescriptor) GetAlias() string

func (*TableDescriptor) GetColumns

func (m *TableDescriptor) GetColumns() []ColumnDescriptor

func (*TableDescriptor) GetID

func (m *TableDescriptor) GetID() ID

func (*TableDescriptor) GetIndexes

func (m *TableDescriptor) GetIndexes() []IndexDescriptor

func (*TableDescriptor) GetModificationTime

func (m *TableDescriptor) GetModificationTime() cockroach_roachpb1.Timestamp

func (*TableDescriptor) GetName

func (m *TableDescriptor) GetName() string

func (*TableDescriptor) GetNextColumnID

func (m *TableDescriptor) GetNextColumnID() ColumnID

func (*TableDescriptor) GetNextIndexID

func (m *TableDescriptor) GetNextIndexID() IndexID

func (*TableDescriptor) GetParentID

func (m *TableDescriptor) GetParentID() ID

func (*TableDescriptor) GetPrimaryIndex

func (m *TableDescriptor) GetPrimaryIndex() IndexDescriptor

func (*TableDescriptor) GetPrivileges

func (m *TableDescriptor) GetPrivileges() *PrivilegeDescriptor

func (*TableDescriptor) GetVersion

func (m *TableDescriptor) GetVersion() uint32

func (*TableDescriptor) Marshal

func (m *TableDescriptor) Marshal() (data []byte, err error)

func (*TableDescriptor) MarshalTo

func (m *TableDescriptor) MarshalTo(data []byte) (int, error)

func (*TableDescriptor) ProtoMessage

func (*TableDescriptor) ProtoMessage()

func (*TableDescriptor) Reset

func (m *TableDescriptor) Reset()

func (*TableDescriptor) SetID

func (desc *TableDescriptor) SetID(id ID)

SetID implements the descriptorProto interface.

func (*TableDescriptor) SetName

func (desc *TableDescriptor) SetName(name string)

SetName implements the descriptorProto interface.

func (*TableDescriptor) Size

func (m *TableDescriptor) Size() (n int)

func (*TableDescriptor) String

func (m *TableDescriptor) String() string

func (*TableDescriptor) TypeName

func (desc *TableDescriptor) TypeName() string

TypeName returns the plain type of this descriptor.

func (*TableDescriptor) Unmarshal

func (m *TableDescriptor) Unmarshal(data []byte) error

func (*TableDescriptor) Validate

func (desc *TableDescriptor) Validate() error

Validate validates that the table descriptor is well formed. Checks include validating the table, column and index names, verifying that column names and index names are unique and verifying that column IDs and index IDs are consistent.

type UserPrivilegeString

type UserPrivilegeString struct {
	User       string
	Privileges string
}

UserPrivilegeString is a pair of strings describing the privileges for a given user.

type UserPrivileges

type UserPrivileges struct {
	User string `protobuf:"bytes,1,opt,name=user" json:"user"`
	// privileges is a bitfield of 1<<Privilege values.
	Privileges uint32 `protobuf:"varint,2,opt,name=privileges" json:"privileges"`
}

UserPrivileges describes the list of privileges available for a given user.

func (*UserPrivileges) Marshal

func (m *UserPrivileges) Marshal() (data []byte, err error)

func (*UserPrivileges) MarshalTo

func (m *UserPrivileges) MarshalTo(data []byte) (int, error)

func (*UserPrivileges) ProtoMessage

func (*UserPrivileges) ProtoMessage()

func (*UserPrivileges) Reset

func (m *UserPrivileges) Reset()

func (*UserPrivileges) Size

func (m *UserPrivileges) Size() (n int)

func (*UserPrivileges) String

func (m *UserPrivileges) String() string

func (*UserPrivileges) Unmarshal

func (m *UserPrivileges) Unmarshal(data []byte) error

Directories

Path Synopsis
Package driver is a generated protocol buffer package.
Package driver is a generated protocol buffer package.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL