本文整理汇总了Golang中github.com/cockroachdb/cockroach/client.Batch.DelRange方法的典型用法代码示例。如果您正苦于以下问题:Golang Batch.DelRange方法的具体用法?Golang Batch.DelRange怎么用?Golang Batch.DelRange使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类github.com/cockroachdb/cockroach/client.Batch
的用法示例。
在下文中一共展示了Batch.DelRange方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: deleteRow
// deleteRow adds to the batch the kv operations necessary to delete a table row
// with the given values.
func (rd *rowDeleter) deleteRow(b *client.Batch, values []parser.Datum) error {
if err := rd.fks.checkAll(values); err != nil {
return err
}
primaryIndexKey, secondaryIndexEntries, err := rd.helper.encodeIndexes(rd.fetchColIDtoRowIndex, values)
if err != nil {
return err
}
for _, secondaryIndexEntry := range secondaryIndexEntries {
if log.V(2) {
log.Infof("Del %s", secondaryIndexEntry.Key)
}
b.Del(secondaryIndexEntry.Key)
}
// Delete the row.
rd.startKey = roachpb.Key(primaryIndexKey)
rd.endKey = rd.startKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %s - %s", rd.startKey, rd.endKey)
}
b.DelRange(&rd.startKey, &rd.endKey, false)
rd.startKey, rd.endKey = nil, nil
return nil
}
示例2: Truncate
// Truncate deletes all rows from a table.
// Privileges: WRITE on table.
// Notes: postgres requires TRUNCATE.
// mysql requires DROP (for mysql >= 5.1.16, DELETE before that).
func (p *planner) Truncate(n *parser.Truncate) (planNode, error) {
b := client.Batch{}
for _, tableQualifiedName := range n.Tables {
tableDesc, err := p.getTableDesc(tableQualifiedName)
if err != nil {
return nil, err
}
if err := p.checkPrivilege(tableDesc, privilege.WRITE); err != nil {
return nil, err
}
tablePrefix := MakeTablePrefix(tableDesc.ID)
// Delete rows and indexes starting with the table's prefix.
tableStartKey := proto.Key(tablePrefix)
tableEndKey := tableStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %q - %q", tableStartKey, tableEndKey)
}
b.DelRange(tableStartKey, tableEndKey)
}
if err := p.txn.Run(&b); err != nil {
return nil, err
}
// TODO(tamird/pmattis): return the number of affected rows
return &valuesNode{}, nil
}
示例3: Truncate
// Truncate deletes all rows from a table.
// Privileges: WRITE on table.
// Notes: postgres requires TRUNCATE.
// mysql requires DROP (for mysql >= 5.1.16, DELETE before that).
func (p *planner) Truncate(n *parser.Truncate) (planNode, error) {
b := client.Batch{}
for _, tableQualifiedName := range n.Tables {
tableDesc, err := p.getTableDesc(tableQualifiedName)
if err != nil {
return nil, err
}
if !tableDesc.HasPrivilege(p.user, parser.PrivilegeWrite) {
return nil, fmt.Errorf("user %s does not have %s privilege on table %s",
p.user, parser.PrivilegeWrite, tableDesc.Name)
}
tablePrefix := encodeTablePrefix(tableDesc.ID)
// Delete rows and indexes starting with the table's prefix.
tableStartKey := proto.Key(tablePrefix)
tableEndKey := tableStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %q - %q", tableStartKey, tableEndKey)
}
b.DelRange(tableStartKey, tableEndKey)
}
if err := p.db.Run(&b); err != nil {
return nil, err
}
// TODO(tamird/pmattis): return the number of affected rows
return &valuesNode{}, nil
}
示例4: Truncate
// Truncate deletes all rows from a table.
// Privileges: DROP on table.
// Notes: postgres requires TRUNCATE.
// mysql requires DROP (for mysql >= 5.1.16, DELETE before that).
func (p *planner) Truncate(n *parser.Truncate) (planNode, *roachpb.Error) {
b := client.Batch{}
for _, tableQualifiedName := range n.Tables {
tableDesc, pErr := p.getTableLease(tableQualifiedName)
if pErr != nil {
return nil, pErr
}
if err := p.checkPrivilege(&tableDesc, privilege.DROP); err != nil {
return nil, roachpb.NewError(err)
}
tablePrefix := keys.MakeTablePrefix(uint32(tableDesc.ID))
// Delete rows and indexes starting with the table's prefix.
tableStartKey := roachpb.Key(tablePrefix)
tableEndKey := tableStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %s - %s", tableStartKey, tableEndKey)
}
b.DelRange(tableStartKey, tableEndKey, false)
}
if pErr := p.txn.Run(&b); pErr != nil {
return nil, pErr
}
return &emptyNode{}, nil
}
示例5: Truncate
// Truncate deletes all rows from a table.
// Privileges: DROP on table.
// Notes: postgres requires TRUNCATE.
// mysql requires DROP (for mysql >= 5.1.16, DELETE before that).
func (p *planner) Truncate(n *parser.Truncate) (planNode, error) {
b := client.Batch{}
for _, tableQualifiedName := range n.Tables {
tableDesc, err := p.getTableDesc(tableQualifiedName)
if err != nil {
return nil, err
}
if err := p.checkPrivilege(tableDesc, privilege.DROP); err != nil {
return nil, err
}
tablePrefix := keys.MakeTablePrefix(uint32(tableDesc.ID))
// Delete rows and indexes starting with the table's prefix.
tableStartKey := proto.Key(tablePrefix)
tableEndKey := tableStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %s - %s", prettyKey(tableStartKey, 0), prettyKey(tableEndKey, 0))
}
b.DelRange(tableStartKey, tableEndKey)
}
if err := p.txn.Run(&b); err != nil {
return nil, err
}
return &valuesNode{}, nil
}
示例6: Delete
// Delete deletes rows from a table.
func (p *planner) Delete(n *parser.Delete) (planNode, error) {
tableDesc, err := p.getAliasedTableDesc(n.Table)
if err != nil {
return nil, err
}
// TODO(tamird,pmattis): avoid going through Select to avoid encoding
// and decoding keys. Also, avoiding Select may provide more
// convenient access to index keys which we are not currently
// deleting.
node, err := p.Select(&parser.Select{
Exprs: parser.SelectExprs{
&parser.StarExpr{TableName: parser.QualifiedName{tableDesc.Name}},
},
From: parser.TableExprs{n.Table},
Where: n.Where,
})
if err != nil {
return nil, err
}
colMap := map[uint32]int{}
for i, name := range node.Columns() {
c, err := tableDesc.FindColumnByName(name)
if err != nil {
return nil, err
}
colMap[c.ID] = i
}
index := tableDesc.Indexes[0]
indexKey := encodeIndexKeyPrefix(tableDesc.ID, index.ID)
b := client.Batch{}
for node.Next() {
if err := node.Err(); err != nil {
return nil, err
}
// TODO(tamird/pmattis): delete the secondary indexes too
primaryKey, err := encodeIndexKey(index, colMap, node.Values(), indexKey)
if err != nil {
return nil, err
}
rowStartKey := proto.Key(primaryKey)
b.DelRange(rowStartKey, rowStartKey.PrefixEnd())
}
if err := p.db.Run(&b); err != nil {
return nil, err
}
// TODO(tamird/pmattis): return the number of affected rows
return &valuesNode{}, nil
}
示例7: truncateTable
// truncateTable truncates the data of a table.
// It deletes a range of data for the table, which includes the PK and all
// indexes.
func truncateTable(tableDesc *sqlbase.TableDescriptor, txn *client.Txn) error {
tablePrefix := keys.MakeTablePrefix(uint32(tableDesc.ID))
// Delete rows and indexes starting with the table's prefix.
tableStartKey := roachpb.Key(tablePrefix)
tableEndKey := tableStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %s - %s", tableStartKey, tableEndKey)
}
b := client.Batch{}
b.DelRange(tableStartKey, tableEndKey, false)
return txn.Run(&b)
}
示例8: Delete
// Delete deletes rows from a table.
func (p *planner) Delete(n *parser.Delete) (planNode, error) {
tableDesc, err := p.getAliasedTableDesc(n.Table)
if err != nil {
return nil, err
}
// TODO(tamird,pmattis): avoid going through Select to avoid encoding
// and decoding keys. Also, avoiding Select may provide more
// convenient access to index keys which we are not currently
// deleting.
node, err := p.Select(&parser.Select{
Exprs: parser.SelectExprs{
&parser.StarExpr{TableName: parser.QualifiedName{tableDesc.Name}},
},
From: parser.TableExprs{n.Table},
Where: n.Where,
})
if err != nil {
return nil, err
}
colMap := map[uint32]int{}
for i, name := range node.Columns() {
c, err := tableDesc.FindColumnByName(name)
if err != nil {
return nil, err
}
colMap[c.ID] = i
}
primaryIndex := tableDesc.Indexes[0]
primaryIndexKeyPrefix := encodeIndexKeyPrefix(tableDesc.ID, primaryIndex.ID)
b := client.Batch{}
for node.Next() {
if err := node.Err(); err != nil {
return nil, err
}
values := node.Values()
primaryIndexKeySuffix, err := encodeIndexKey(primaryIndex, colMap, values, nil)
if err != nil {
return nil, err
}
primaryIndexKey := bytes.Join([][]byte{primaryIndexKeyPrefix, primaryIndexKeySuffix}, nil)
// Delete the secondary indexes.
secondaryIndexEntries, err := encodeSecondaryIndexes(tableDesc, colMap, values, primaryIndexKeySuffix)
if err != nil {
return nil, err
}
for _, secondaryIndexEntry := range secondaryIndexEntries {
if log.V(2) {
log.Infof("Del %q", secondaryIndexEntry.key)
}
b.Del(secondaryIndexEntry.key)
}
// Delete the row.
rowStartKey := proto.Key(primaryIndexKey)
rowEndKey := rowStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %q - %q", rowStartKey, rowEndKey)
}
b.DelRange(rowStartKey, rowEndKey)
}
if err := p.db.Run(&b); err != nil {
return nil, err
}
// TODO(tamird/pmattis): return the number of affected rows
return &valuesNode{}, nil
}
示例9: Delete
// Delete deletes rows from a table.
// Privileges: DELETE and SELECT on table. We currently always use a SELECT statement.
// Notes: postgres requires DELETE. Also requires SELECT for "USING" and "WHERE" with tables.
// mysql requires DELETE. Also requires SELECT if a table is used in the "WHERE" clause.
func (p *planner) Delete(n *parser.Delete) (planNode, *roachpb.Error) {
tableDesc, pErr := p.getAliasedTableLease(n.Table)
if pErr != nil {
return nil, pErr
}
if err := p.checkPrivilege(tableDesc, privilege.DELETE); err != nil {
return nil, roachpb.NewError(err)
}
// TODO(tamird,pmattis): avoid going through Select to avoid encoding
// and decoding keys.
rows, pErr := p.Select(&parser.Select{
Exprs: tableDesc.allColumnsSelector(),
From: parser.TableExprs{n.Table},
Where: n.Where,
})
if pErr != nil {
return nil, pErr
}
if p.prepareOnly {
return nil, nil
}
// Construct a map from column ID to the index the value appears at within a
// row.
colIDtoRowIndex, err := makeColIDtoRowIndex(rows, tableDesc)
if err != nil {
return nil, roachpb.NewError(err)
}
primaryIndex := tableDesc.PrimaryIndex
primaryIndexKeyPrefix := MakeIndexKeyPrefix(tableDesc.ID, primaryIndex.ID)
b := client.Batch{}
result := &valuesNode{}
for rows.Next() {
rowVals := rows.Values()
result.rows = append(result.rows, parser.DTuple(nil))
primaryIndexKey, _, err := encodeIndexKey(
&primaryIndex, colIDtoRowIndex, rowVals, primaryIndexKeyPrefix)
if err != nil {
return nil, roachpb.NewError(err)
}
// Delete the secondary indexes.
indexes := tableDesc.Indexes
// Also include all the indexes under mutation; mutation state is
// irrelevant for deletions.
for _, m := range tableDesc.Mutations {
if index := m.GetIndex(); index != nil {
indexes = append(indexes, *index)
}
}
secondaryIndexEntries, err := encodeSecondaryIndexes(
tableDesc.ID, indexes, colIDtoRowIndex, rowVals)
if err != nil {
return nil, roachpb.NewError(err)
}
for _, secondaryIndexEntry := range secondaryIndexEntries {
if log.V(2) {
log.Infof("Del %s", secondaryIndexEntry.key)
}
b.Del(secondaryIndexEntry.key)
}
// Delete the row.
rowStartKey := roachpb.Key(primaryIndexKey)
rowEndKey := rowStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %s - %s", rowStartKey, rowEndKey)
}
b.DelRange(rowStartKey, rowEndKey)
}
if pErr := rows.PErr(); pErr != nil {
return nil, pErr
}
if isSystemConfigID(tableDesc.GetID()) {
// Mark transaction as operating on the system DB.
p.txn.SetSystemConfigTrigger()
}
if pErr := p.txn.Run(&b); pErr != nil {
return nil, pErr
}
return result, nil
}
示例10: backfillBatch
func (p *planner) backfillBatch(b *client.Batch, tableName *parser.QualifiedName, oldTableDesc, newTableDesc *TableDescriptor) error {
table := &parser.AliasedTableExpr{Expr: tableName}
var droppedColumnDescs []ColumnDescriptor
var droppedIndexDescs []IndexDescriptor
var newIndexDescs []IndexDescriptor
for _, m := range oldTableDesc.Mutations {
switch m.Direction {
case DescriptorMutation_ADD:
switch t := m.Descriptor_.(type) {
case *DescriptorMutation_Column:
// TODO(vivek): Add column to new columns and use it
// to fill in default values.
case *DescriptorMutation_Index:
newIndexDescs = append(newIndexDescs, *t.Index)
}
case DescriptorMutation_DROP:
switch t := m.Descriptor_.(type) {
case *DescriptorMutation_Column:
droppedColumnDescs = append(droppedColumnDescs, *t.Column)
case *DescriptorMutation_Index:
droppedIndexDescs = append(droppedIndexDescs, *t.Index)
}
}
}
if len(droppedColumnDescs) > 0 {
var updateExprs parser.UpdateExprs
for _, droppedColumnDesc := range droppedColumnDescs {
updateExprs = append(updateExprs, &parser.UpdateExpr{
Names: parser.QualifiedNames{&parser.QualifiedName{Base: parser.Name(droppedColumnDesc.Name)}},
Expr: parser.DNull,
})
}
// Run `UPDATE <table> SET col1 = NULL, col2 = NULL, ...` to clear
// the data stored in the columns being dropped.
if _, err := p.Update(&parser.Update{
Table: table,
Exprs: updateExprs,
}); err != nil {
return err
}
}
for _, indexDescriptor := range droppedIndexDescs {
indexPrefix := MakeIndexKeyPrefix(newTableDesc.ID, indexDescriptor.ID)
// Delete the index.
indexStartKey := roachpb.Key(indexPrefix)
indexEndKey := indexStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %s - %s", prettyKey(indexStartKey, 0), prettyKey(indexEndKey, 0))
}
b.DelRange(indexStartKey, indexEndKey)
}
if len(newIndexDescs) > 0 {
// Get all the rows affected.
// TODO(vivek): Avoid going through Select.
// TODO(tamird): Support partial indexes?
rows, err := p.Select(&parser.Select{
Exprs: parser.SelectExprs{parser.StarSelectExpr()},
From: parser.TableExprs{table},
})
if err != nil {
return err
}
// Construct a map from column ID to the index the value appears at within a
// row.
colIDtoRowIndex, err := makeColIDtoRowIndex(rows, oldTableDesc)
if err != nil {
return err
}
// TODO(tamird): This will fall down in production use. We need to do
// something better (see #2036). In particular, this implementation
// has the following problems:
// - Very large tables will generate an enormous batch here. This
// isn't really a problem in itself except that it will exacerbate
// the other issue:
// - Any non-quiescent table that this runs against will end up with
// an inconsistent index. This is because as inserts/updates continue
// to roll in behind this operation's read front, the written index
// will become incomplete/stale before it's written.
for rows.Next() {
rowVals := rows.Values()
for _, newIndexDesc := range newIndexDescs {
secondaryIndexEntries, err := encodeSecondaryIndexes(
oldTableDesc.ID, []IndexDescriptor{newIndexDesc}, colIDtoRowIndex, rowVals)
if err != nil {
return err
}
for _, secondaryIndexEntry := range secondaryIndexEntries {
//.........这里部分代码省略.........
示例11: Delete
// Delete deletes rows from a table.
// Privileges: WRITE and READ on table. We currently always use a SELECT statement.
// Notes: postgres requires DELETE. Also requires SELECT for "USING" and "WHERE" with tables.
// mysql requires DELETE. Also requires SELECT if a table is used in the "WHERE" clause.
func (p *planner) Delete(n *parser.Delete) (planNode, error) {
tableDesc, err := p.getAliasedTableDesc(n.Table)
if err != nil {
return nil, err
}
if !tableDesc.HasPrivilege(p.user, parser.PrivilegeWrite) {
return nil, fmt.Errorf("user %s does not have %s privilege on table %s",
p.user, parser.PrivilegeWrite, tableDesc.Name)
}
// TODO(tamird,pmattis): avoid going through Select to avoid encoding
// and decoding keys. Also, avoiding Select may provide more
// convenient access to index keys which we are not currently
// deleting.
node, err := p.Select(&parser.Select{
Exprs: parser.SelectExprs{
&parser.StarExpr{TableName: &parser.QualifiedName{Base: parser.Name(tableDesc.Name)}},
},
From: parser.TableExprs{n.Table},
Where: n.Where,
})
if err != nil {
return nil, err
}
// Construct a map from column ID to the index the value appears at within a
// row.
colIDtoRowIndex := map[structured.ID]int{}
for i, name := range node.Columns() {
c, err := tableDesc.FindColumnByName(name)
if err != nil {
return nil, err
}
colIDtoRowIndex[c.ID] = i
}
primaryIndex := tableDesc.PrimaryIndex
primaryIndexKeyPrefix := structured.MakeIndexKeyPrefix(tableDesc.ID, primaryIndex.ID)
b := client.Batch{}
for node.Next() {
if err := node.Err(); err != nil {
return nil, err
}
values := node.Values()
primaryIndexKeySuffix, _, err := encodeIndexKey(primaryIndex.ColumnIDs, colIDtoRowIndex, values, nil)
if err != nil {
return nil, err
}
primaryIndexKey := bytes.Join([][]byte{primaryIndexKeyPrefix, primaryIndexKeySuffix}, nil)
// Delete the secondary indexes.
secondaryIndexEntries, err := encodeSecondaryIndexes(tableDesc.ID, tableDesc.Indexes, colIDtoRowIndex, values, primaryIndexKeySuffix)
if err != nil {
return nil, err
}
for _, secondaryIndexEntry := range secondaryIndexEntries {
if log.V(2) {
log.Infof("Del %q", secondaryIndexEntry.key)
}
b.Del(secondaryIndexEntry.key)
}
// Delete the row.
rowStartKey := proto.Key(primaryIndexKey)
rowEndKey := rowStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %q - %q", rowStartKey, rowEndKey)
}
b.DelRange(rowStartKey, rowEndKey)
}
if err := p.db.Run(&b); err != nil {
return nil, err
}
// TODO(tamird/pmattis): return the number of affected rows
return &valuesNode{}, nil
}
示例12: backfillBatch
func (p *planner) backfillBatch(b *client.Batch, oldTableDesc *TableDescriptor, mutationID MutationID) *roachpb.Error {
var droppedColumnDescs []ColumnDescriptor
var droppedIndexDescs []IndexDescriptor
var newIndexDescs []IndexDescriptor
// Collect the elements that are part of the mutation.
for _, m := range oldTableDesc.Mutations {
if m.MutationID != mutationID {
// Mutations are applied in a FIFO order. Only apply the first set of
// mutations if they have the mutation ID we're looking for.
break
}
switch m.Direction {
case DescriptorMutation_ADD:
switch t := m.Descriptor_.(type) {
case *DescriptorMutation_Column:
// TODO(vivek): Add column to new columns and use it
// to fill in default values.
case *DescriptorMutation_Index:
newIndexDescs = append(newIndexDescs, *t.Index)
}
case DescriptorMutation_DROP:
switch t := m.Descriptor_.(type) {
case *DescriptorMutation_Column:
droppedColumnDescs = append(droppedColumnDescs, *t.Column)
case *DescriptorMutation_Index:
droppedIndexDescs = append(droppedIndexDescs, *t.Index)
}
}
}
// TODO(vivek): Break these backfill operations into chunks. All of them
// will fail on big tables (see #3274).
// Delete the entire dropped columns.
// This used to use SQL UPDATE in the past to update the dropped
// column to NULL; but a column in the process of being
// dropped is placed in the table descriptor mutations, and
// a SQL UPDATE of a column in mutations will fail.
if len(droppedColumnDescs) > 0 {
// Run a scan across the table using the primary key.
start := roachpb.Key(MakeIndexKeyPrefix(oldTableDesc.ID, oldTableDesc.PrimaryIndex.ID))
// Use a different batch to perform the scan.
batch := &client.Batch{}
batch.Scan(start, start.PrefixEnd(), 0)
if pErr := p.txn.Run(batch); pErr != nil {
return pErr
}
for _, result := range batch.Results {
var sentinelKey roachpb.Key
for _, kv := range result.Rows {
if sentinelKey == nil || !bytes.HasPrefix(kv.Key, sentinelKey) {
// Sentinel keys have a 0 suffix indicating 0 bytes of column
// ID. Strip off that suffix to determine the prefix shared with the
// other keys for the row.
sentinelKey = stripColumnIDLength(kv.Key)
for _, columnDesc := range droppedColumnDescs {
// Delete the dropped column.
colKey := keys.MakeColumnKey(sentinelKey, uint32(columnDesc.ID))
if log.V(2) {
log.Infof("Del %s", colKey)
}
b.Del(colKey)
}
}
}
}
}
for _, indexDescriptor := range droppedIndexDescs {
indexPrefix := MakeIndexKeyPrefix(oldTableDesc.ID, indexDescriptor.ID)
// Delete the index.
indexStartKey := roachpb.Key(indexPrefix)
indexEndKey := indexStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %s - %s", indexStartKey, indexEndKey)
}
b.DelRange(indexStartKey, indexEndKey)
}
if len(newIndexDescs) > 0 {
// Get all the rows affected.
// TODO(vivek): Avoid going through Select.
// TODO(tamird): Support partial indexes?
// Use a scanNode with SELECT to pass in a TableDescriptor
// to the SELECT without needing to use a parser.QualifiedName,
// because we want to run schema changes from a gossip feed of
// table IDs.
scan := &scanNode{
planner: p,
txn: p.txn,
desc: oldTableDesc,
}
scan.initDescDefaults()
rows, pErr := p.selectIndex(&selectNode{}, scan, nil, false)
if pErr != nil {
return pErr
//.........这里部分代码省略.........
示例13: backfillBatch
func (p *planner) backfillBatch(b *client.Batch, oldTableDesc, newTableDesc *TableDescriptor) error {
var droppedColumnDescs []ColumnDescriptor
var droppedIndexDescs []IndexDescriptor
var newIndexDescs []IndexDescriptor
for _, m := range oldTableDesc.Mutations {
switch m.Direction {
case DescriptorMutation_ADD:
switch t := m.Descriptor_.(type) {
case *DescriptorMutation_Column:
// TODO(vivek): Add column to new columns and use it
// to fill in default values.
case *DescriptorMutation_Index:
newIndexDescs = append(newIndexDescs, *t.Index)
}
case DescriptorMutation_DROP:
switch t := m.Descriptor_.(type) {
case *DescriptorMutation_Column:
droppedColumnDescs = append(droppedColumnDescs, *t.Column)
case *DescriptorMutation_Index:
droppedIndexDescs = append(droppedIndexDescs, *t.Index)
}
}
}
// TODO(vivek): Break these backfill operations into chunks. All of them
// will fail on big tables.
// Delete the entire dropped columns.
// This used to use SQL UPDATE in the past to update the dropped
// column to NULL; but a column in the process of being
// dropped is placed in the table descriptor mutations, and
// a SQL UPDATE of a column in mutations will fail.
if len(droppedColumnDescs) > 0 {
// Run a scan across the table using the primary key.
start := roachpb.Key(MakeIndexKeyPrefix(newTableDesc.ID, newTableDesc.PrimaryIndex.ID))
// Use a different batch to perform the scan.
batch := &client.Batch{}
batch.Scan(start, start.PrefixEnd(), 0)
if err := p.txn.Run(batch); err != nil {
return err
}
for _, result := range batch.Results {
var sentinelKey roachpb.Key
for _, kv := range result.Rows {
if sentinelKey == nil || !bytes.HasPrefix(kv.Key, sentinelKey) {
// Sentinel keys have a 0 suffix indicating 0 bytes of column
// ID. Strip off that suffix to determine the prefix shared with the
// other keys for the row.
sentinelKey = stripColumnIDLength(kv.Key)
for _, columnDesc := range droppedColumnDescs {
// Delete the dropped column.
colKey := keys.MakeColumnKey(sentinelKey, uint32(columnDesc.ID))
if log.V(2) {
log.Infof("Del %s", colKey)
}
b.Del(colKey)
}
}
}
}
}
for _, indexDescriptor := range droppedIndexDescs {
indexPrefix := MakeIndexKeyPrefix(newTableDesc.ID, indexDescriptor.ID)
// Delete the index.
indexStartKey := roachpb.Key(indexPrefix)
indexEndKey := indexStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %s - %s", indexStartKey, indexEndKey)
}
b.DelRange(indexStartKey, indexEndKey)
}
if len(newIndexDescs) > 0 {
// Get all the rows affected.
// TODO(vivek): Avoid going through Select.
// TODO(tamird): Support partial indexes?
// Use a scanNode with SELECT to pass in a TableDescriptor
// to the SELECT without needing to use a parser.QualifiedName,
// because we want to run schema changes from a gossip feed of
// table IDs.
scan := &scanNode{
planner: p,
txn: p.txn,
desc: oldTableDesc,
}
scan.initDescDefaults()
rows, err := p.selectWithScan(scan, &parser.Select{Exprs: oldTableDesc.allColumnsSelector()})
if err != nil {
return err
}
// Construct a map from column ID to the index the value appears at within a
// row.
colIDtoRowIndex, err := makeColIDtoRowIndex(rows, oldTableDesc)
if err != nil {
//.........这里部分代码省略.........
示例14: DropIndex
// DropIndex drops an index.
// Privileges: CREATE on table.
// Notes: postgres allows only the index owner to DROP an index.
// mysql requires the INDEX privilege on the table.
func (p *planner) DropIndex(n *parser.DropIndex) (planNode, error) {
var b client.Batch
for _, indexQualifiedName := range n.Names {
if err := indexQualifiedName.NormalizeTableName(p.session.Database); err != nil {
return nil, err
}
tableDesc, err := p.getTableDesc(indexQualifiedName)
if err != nil {
return nil, err
}
idxName := indexQualifiedName.Index()
idx, err := tableDesc.FindIndexByName(idxName)
if err != nil {
if n.IfExists {
// Noop.
return &valuesNode{}, nil
}
// Index does not exist, but we want it to: error out.
return nil, fmt.Errorf("index %q does not exist", idxName)
}
if err := p.checkPrivilege(tableDesc, privilege.CREATE); err != nil {
return nil, err
}
indexPrefix := MakeIndexKeyPrefix(tableDesc.ID, idx.ID)
// Delete the index.
indexStartKey := proto.Key(indexPrefix)
indexEndKey := indexStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %q - %q", indexStartKey, indexEndKey)
}
b.DelRange(indexStartKey, indexEndKey)
found := false
for i := range tableDesc.Indexes {
if &tableDesc.Indexes[i] == idx {
tableDesc.Indexes = append(tableDesc.Indexes[:i], tableDesc.Indexes[i+1:]...)
found = true
break
}
}
if !found {
return nil, util.Errorf("index %s not found in %s", idx, tableDesc)
}
descKey := MakeDescMetadataKey(tableDesc.GetID())
if err := tableDesc.Validate(); err != nil {
return nil, err
}
if err := p.txn.Put(descKey, tableDesc); err != nil {
return nil, err
}
// Mark transaction as operating on the system DB.
p.txn.SetSystemDBTrigger()
}
if err := p.txn.Run(&b).GoError(); err != nil {
return nil, err
}
return &valuesNode{}, nil
}
示例15: Delete
// Delete deletes rows from a table.
// Privileges: DELETE and SELECT on table. We currently always use a SELECT statement.
// Notes: postgres requires DELETE. Also requires SELECT for "USING" and "WHERE" with tables.
// mysql requires DELETE. Also requires SELECT if a table is used in the "WHERE" clause.
func (p *planner) Delete(n *parser.Delete) (planNode, error) {
tableDesc, err := p.getAliasedTableDesc(n.Table, false /* !allowCache */)
if err != nil {
return nil, err
}
if err := p.checkPrivilege(tableDesc, privilege.DELETE); err != nil {
return nil, err
}
// TODO(tamird,pmattis): avoid going through Select to avoid encoding
// and decoding keys. Also, avoiding Select may provide more
// convenient access to index keys which we are not currently
// deleting.
rows, err := p.Select(&parser.Select{
Exprs: parser.SelectExprs{parser.StarSelectExpr()},
From: parser.TableExprs{n.Table},
Where: n.Where,
})
if err != nil {
return nil, err
}
// Construct a map from column ID to the index the value appears at within a
// row.
colIDtoRowIndex := map[ColumnID]int{}
for i, name := range rows.Columns() {
c, err := tableDesc.FindColumnByName(name)
if err != nil {
return nil, err
}
colIDtoRowIndex[c.ID] = i
}
primaryIndex := tableDesc.PrimaryIndex
primaryIndexKeyPrefix := MakeIndexKeyPrefix(tableDesc.ID, primaryIndex.ID)
b := client.Batch{}
result := &valuesNode{}
for rows.Next() {
rowVals := rows.Values()
result.rows = append(result.rows, parser.DTuple(nil))
primaryIndexKey, _, err := encodeIndexKey(
primaryIndex.ColumnIDs, colIDtoRowIndex, rowVals, primaryIndexKeyPrefix)
if err != nil {
return nil, err
}
// Delete the secondary indexes.
secondaryIndexEntries, err := encodeSecondaryIndexes(
tableDesc.ID, tableDesc.Indexes, colIDtoRowIndex, rowVals)
if err != nil {
return nil, err
}
for _, secondaryIndexEntry := range secondaryIndexEntries {
if log.V(2) {
log.Infof("Del %s", prettyKey(secondaryIndexEntry.key, 0))
}
b.Del(secondaryIndexEntry.key)
}
// Delete the row.
rowStartKey := roachpb.Key(primaryIndexKey)
rowEndKey := rowStartKey.PrefixEnd()
if log.V(2) {
log.Infof("DelRange %s - %s", prettyKey(rowStartKey, 0), prettyKey(rowEndKey, 0))
}
b.DelRange(rowStartKey, rowEndKey)
}
if err := rows.Err(); err != nil {
return nil, err
}
if err := p.txn.Run(&b); err != nil {
return nil, err
}
return result, nil
}