func runDel(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() return } count := len(args) keys := make([]string, 0, count) for i := 0; i < count; i++ { keys = append(keys, unquoteArg(args[i], true /* disallow system keys */)) } kvDB := makeDBClient() if kvDB == nil { return } var b client.Batch for i := 0; i < count; i++ { b.Del(keys[i]) } if err := kvDB.Run(&b); err != nil { fmt.Fprintf(osStderr, "delete failed: %s\n", err) osExit(1) return } }
// 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 }
// RenameDatabase renames the database. // Privileges: security.RootUser user. // Notes: postgres requires superuser, db owner, or "CREATEDB". // mysql >= 5.1.23 does not allow database renames. func (p *planner) RenameDatabase(n *parser.RenameDatabase) (planNode, error) { if n.Name == "" || n.NewName == "" { return nil, errEmptyDatabaseName } if p.session.User != security.RootUser { return nil, fmt.Errorf("only %s is allowed to rename databases", security.RootUser) } dbDesc, err := p.getDatabaseDesc(string(n.Name)) if err != nil { return nil, err } if dbDesc == nil { return nil, databaseDoesNotExistError(string(n.Name)) } if n.Name == n.NewName { // Noop. return &emptyNode{}, nil } // Now update the nameMetadataKey and the descriptor. descKey := sqlbase.MakeDescMetadataKey(dbDesc.GetID()) dbDesc.SetName(string(n.NewName)) if err := dbDesc.Validate(); err != nil { return nil, err } newKey := databaseKey{string(n.NewName)}.Key() oldKey := databaseKey{string(n.Name)}.Key() descID := dbDesc.GetID() descDesc := sqlbase.WrapDescriptor(dbDesc) b := client.Batch{} b.CPut(newKey, descID, nil) b.Put(descKey, descDesc) b.Del(oldKey) if err := p.txn.Run(&b); err != nil { if _, ok := err.(*roachpb.ConditionFailedError); ok { return nil, fmt.Errorf("the new database name %q already exists", string(n.NewName)) } return nil, err } p.setTestingVerifyMetadata(func(systemConfig config.SystemConfig) error { if err := expectDescriptorID(systemConfig, newKey, descID); err != nil { return err } if err := expectDescriptor(systemConfig, descKey, descDesc); err != nil { return err } return expectDeleted(systemConfig, oldKey) }) return &emptyNode{}, nil }
// flush writes all dirty nodes and the tree to the transaction. func (tc *treeContext) flush(b *client.Batch) { if tc.dirty { b.Put(keys.RangeTreeRoot, tc.tree) } for key, cachedNode := range tc.nodes { if cachedNode.dirty { if cachedNode.node == nil { b.Del(keys.RangeTreeNodeKey(roachpb.RKey(key))) } else { b.Put(keys.RangeTreeNodeKey(roachpb.RKey(key)), cachedNode.node) } } } }
func runDel(cmd *cobra.Command, args []string) { if len(args) == 0 { mustUsage(cmd) return } var b client.Batch for _, arg := range args { b.Del(unquoteArg(arg, true /* disallow system keys */)) } kvDB, stopper := makeDBClient() defer stopper.Stop() if err := kvDB.Run(&b); err != nil { panicf("delete failed: %s", err) } }
// RenameDatabase renames the database. // Privileges: "root" user. // Notes: postgres requires superuser, db owner, or "CREATEDB". // mysql >= 5.1.23 does not allow database renames. func (p *planner) RenameDatabase(n *parser.RenameDatabase) (planNode, error) { if n.Name == "" || n.NewName == "" { return nil, errEmptyDatabaseName } if p.user != security.RootUser { return nil, fmt.Errorf("only %s is allowed to rename databases", security.RootUser) } dbDesc, err := p.getDatabaseDesc(string(n.Name)) if err != nil { return nil, err } if n.Name == n.NewName { // Noop. return &valuesNode{}, nil } // Now update the nameMetadataKey and the descriptor. descKey := MakeDescMetadataKey(dbDesc.GetID()) dbDesc.SetName(string(n.NewName)) if err := dbDesc.Validate(); err != nil { return nil, err } b := client.Batch{} b.CPut(databaseKey{string(n.NewName)}.Key(), dbDesc.GetID(), nil) b.Put(descKey, dbDesc) b.Del(databaseKey{string(n.Name)}.Key()) // Mark transaction as operating on the system DB. p.txn.SetSystemDBTrigger() if err := p.txn.Run(&b); err != nil { if _, ok := err.(*proto.ConditionFailedError); ok { return nil, fmt.Errorf("the new database name %q already exists", string(n.NewName)) } return nil, err } return &valuesNode{}, nil }
func runDel(cmd *cobra.Command, args []string) { if len(args) == 0 { cmd.Usage() return } var b client.Batch for _, arg := range args { b.Del(unquoteArg(arg, true /* disallow system keys */)) } kvDB, stopper := makeDBClient() defer stopper.Stop() if err := kvDB.Run(&b); err != nil { fmt.Fprintf(osStderr, "delete failed: %s\n", err) osExit(1) return } }
// RenameTable renames the table. // Privileges: WRITE on database. // Notes: postgres requires the table owner. // mysql requires ALTER, DROP on the original table, and CREATE, INSERT // on the new table (and does not copy privileges over). func (p *planner) RenameTable(n *parser.RenameTable) (planNode, error) { if n.NewName == "" { return nil, errEmptyTableName } if err := n.Name.NormalizeTableName(p.session.Database); err != nil { return nil, err } if n.Name.Table() == string(n.NewName) { // Noop. return &valuesNode{}, nil } dbDesc, err := p.getDatabaseDesc(n.Name.Database()) if err != nil { return nil, err } tbKey := tableKey{dbDesc.ID, string(n.Name.Table())}.Key() // Check if table exists. gr, err := p.txn.Get(tbKey) if err != nil { return nil, err } if !gr.Exists() { if n.IfExists { // Noop. return &valuesNode{}, nil } // Key does not exist, but we want it to: error out. return nil, fmt.Errorf("table %q does not exist", n.Name.Table()) } if err := p.checkPrivilege(dbDesc, privilege.WRITE); err != nil { return nil, err } tableDesc, err := p.getTableDesc(n.Name) if err != nil { return nil, err } tableDesc.SetName(string(n.NewName)) newTbKey := tableKey{dbDesc.ID, string(n.NewName)}.Key() descKey := MakeDescMetadataKey(tableDesc.GetID()) b := client.Batch{} b.Put(descKey, tableDesc) b.CPut(newTbKey, descKey, nil) b.Del(tbKey) if err := p.txn.Run(&b); err != nil { if _, ok := err.(*proto.ConditionFailedError); ok { return nil, fmt.Errorf("table name %q already exists", n.NewName) } return nil, err } return &valuesNode{}, nil }
// RenameTable renames the table. // Privileges: DROP on source table, CREATE on destination database. // Notes: postgres requires the table owner. // mysql requires ALTER, DROP on the original table, and CREATE, INSERT // on the new table (and does not copy privileges over). func (p *planner) RenameTable(n *parser.RenameTable) (planNode, *roachpb.Error) { if err := n.NewName.NormalizeTableName(p.session.Database); err != nil { return nil, roachpb.NewError(err) } if n.NewName.Table() == "" { return nil, roachpb.NewError(errEmptyTableName) } if err := n.Name.NormalizeTableName(p.session.Database); err != nil { return nil, roachpb.NewError(err) } dbDesc, pErr := p.getDatabaseDesc(n.Name.Database()) if pErr != nil { return nil, pErr } tbKey := tableKey{dbDesc.ID, n.Name.Table()}.Key() // Check if table exists. gr, pErr := p.txn.Get(tbKey) if pErr != nil { return nil, pErr } if !gr.Exists() { if n.IfExists { // Noop. return &valuesNode{}, nil } // Key does not exist, but we want it to: error out. return nil, roachpb.NewUErrorf("table %q does not exist", n.Name.Table()) } targetDbDesc, pErr := p.getDatabaseDesc(n.NewName.Database()) if pErr != nil { return nil, pErr } if pErr := p.checkPrivilege(targetDbDesc, privilege.CREATE); pErr != nil { return nil, pErr } if n.Name.Database() == n.NewName.Database() && n.Name.Table() == n.NewName.Table() { // Noop. return &valuesNode{}, nil } tableDesc, pErr := p.getTableDesc(n.Name) if pErr != nil { return nil, pErr } if pErr := p.checkPrivilege(tableDesc, privilege.DROP); pErr != nil { return nil, pErr } tableDesc.SetName(n.NewName.Table()) tableDesc.ParentID = targetDbDesc.ID descKey := MakeDescMetadataKey(tableDesc.GetID()) newTbKey := tableKey{targetDbDesc.ID, n.NewName.Table()}.Key() if err := tableDesc.Validate(); err != nil { return nil, roachpb.NewError(err) } descID := tableDesc.GetID() descDesc := wrapDescriptor(tableDesc) b := client.Batch{} b.Put(descKey, descDesc) b.CPut(newTbKey, descID, nil) b.Del(tbKey) if pErr := p.txn.Run(&b); pErr != nil { if _, ok := pErr.GoError().(*roachpb.ConditionFailedError); ok { return nil, roachpb.NewUErrorf("table name %q already exists", n.NewName.Table()) } return nil, pErr } p.testingVerifyMetadata = func(systemConfig config.SystemConfig) error { if err := expectDescriptorID(systemConfig, newTbKey, descID); err != nil { return err } if err := expectDescriptor(systemConfig, descKey, descDesc); err != nil { return err } return expectDeleted(systemConfig, tbKey) } return &valuesNode{}, nil }
// 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 }
// Update updates columns for a selection of rows from a table. // Privileges: UPDATE and SELECT on table. We currently always use a select statement. // Notes: postgres requires UPDATE. Requires SELECT with WHERE clause with table. // mysql requires UPDATE. Also requires SELECT with WHERE clause with table. func (p *planner) Update(n *parser.Update) (planNode, error) { tableDesc, err := p.getAliasedTableDesc(n.Table) if err != nil { return nil, err } if err := p.checkPrivilege(tableDesc, privilege.UPDATE); err != nil { return nil, err } // Determine which columns we're inserting into. var names parser.QualifiedNames for _, expr := range n.Exprs { names = append(names, expr.Name) } cols, err := p.processColumns(tableDesc, names) if err != nil { return nil, err } // Set of columns being updated colIDSet := map[ColumnID]struct{}{} for _, c := range cols { colIDSet[c.ID] = struct{}{} } // Don't allow updating any column that is part of the primary key. for i, id := range tableDesc.PrimaryIndex.ColumnIDs { if _, ok := colIDSet[id]; ok { return nil, fmt.Errorf("primary key column %q cannot be updated", tableDesc.PrimaryIndex.ColumnNames[i]) } } // Generate the list of select targets. We need to select all of the columns // plus we select all of the update expressions in case those expressions // reference columns (e.g. "UPDATE t SET v = v + 1"). targets := make(parser.SelectExprs, 0, len(n.Exprs)+1) targets = append(targets, parser.StarSelectExpr()) for _, expr := range n.Exprs { targets = append(targets, parser.SelectExpr{Expr: expr.Expr}) } // Query the rows that need updating. rows, err := p.Select(&parser.Select{ Exprs: targets, 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, col := range tableDesc.Columns { colIDtoRowIndex[col.ID] = i } primaryIndex := tableDesc.PrimaryIndex primaryIndexKeyPrefix := MakeIndexKeyPrefix(tableDesc.ID, primaryIndex.ID) // Secondary indexes needing updating. var indexes []IndexDescriptor for _, index := range tableDesc.Indexes { for _, id := range index.ColumnIDs { if _, ok := colIDSet[id]; ok { indexes = append(indexes, index) break } } } // Update all the rows. var b client.Batch for rows.Next() { rowVals := rows.Values() primaryIndexKey, _, err := encodeIndexKey( primaryIndex.ColumnIDs, colIDtoRowIndex, rowVals, primaryIndexKeyPrefix) if err != nil { return nil, err } // Compute the current secondary index key:value pairs for this row. secondaryIndexEntries, err := encodeSecondaryIndexes( tableDesc.ID, indexes, colIDtoRowIndex, rowVals) if err != nil { return nil, err } // Our updated value expressions occur immediately after the plain // columns in the output. newVals := rowVals[len(tableDesc.Columns):] // Update the row values. for i, col := range cols { val := newVals[i] if !col.Nullable && val == parser.DNull { return nil, fmt.Errorf("null value in column %q violates not-null constraint", col.Name) } rowVals[colIDtoRowIndex[col.ID]] = val } // Compute the new secondary index key:value pairs for this row. newSecondaryIndexEntries, err := encodeSecondaryIndexes( tableDesc.ID, indexes, colIDtoRowIndex, rowVals) if err != nil { return nil, err } // Update secondary indexes. for i, newSecondaryIndexEntry := range newSecondaryIndexEntries { secondaryIndexEntry := secondaryIndexEntries[i] if !bytes.Equal(newSecondaryIndexEntry.key, secondaryIndexEntry.key) { if log.V(2) { log.Infof("CPut %q -> %v", newSecondaryIndexEntry.key, newSecondaryIndexEntry.value) } b.CPut(newSecondaryIndexEntry.key, newSecondaryIndexEntry.value, nil) if log.V(2) { log.Infof("Del %q", secondaryIndexEntry.key) } b.Del(secondaryIndexEntry.key) } } // Add the new values. for i, val := range newVals { col := cols[i] primitive, err := convertDatum(col, val) if err != nil { return nil, err } key := MakeColumnKey(col.ID, primaryIndexKey) if primitive != nil { // We only output non-NULL values. Non-existent column keys are // considered NULL during scanning and the row sentinel ensures we know // the row exists. if log.V(2) { log.Infof("Put %q -> %v", key, val) } b.Put(key, primitive) } else { // The column might have already existed but is being set to NULL, so // delete it. if log.V(2) { log.Infof("Del %q", key) } b.Del(key) } } } if err := rows.Err(); err != nil { return nil, err } if err := p.txn.Run(&b); err != nil { return nil, convertBatchError(tableDesc, b, err) } // TODO(tamird/pmattis): return the number of affected rows. return &valuesNode{}, nil }
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 } // Construct a map from column ID to the index the value appears at within a // row. colIDtoRowIndex, pErr := makeColIDtoRowIndex(rows, oldTableDesc) if pErr != nil { return pErr } for rows.Next() { rowVals := rows.Values() for _, newIndexDesc := range newIndexDescs { secondaryIndexEntries, pErr := encodeSecondaryIndexes( oldTableDesc.ID, []IndexDescriptor{newIndexDesc}, colIDtoRowIndex, rowVals) if pErr != nil { return pErr } for _, secondaryIndexEntry := range secondaryIndexEntries { if log.V(2) { log.Infof("CPut %s -> %v", secondaryIndexEntry.key, secondaryIndexEntry.value) } b.CPut(secondaryIndexEntry.key, secondaryIndexEntry.value, nil) } } } return rows.PErr() } return nil }
// updateRow adds to the batch the kv operations necessary to update a table row // with the given values. // // The row corresponding to oldValues is updated with the ones in updateValues. // Note that updateValues only contains the ones that are changing. // // The return value is only good until the next call to UpdateRow. func (ru *rowUpdater) updateRow( b *client.Batch, oldValues []parser.Datum, updateValues []parser.Datum, ) ([]parser.Datum, error) { if len(oldValues) != len(ru.fetchCols) { return nil, util.Errorf("got %d values but expected %d", len(oldValues), len(ru.fetchCols)) } if len(updateValues) != len(ru.updateCols) { return nil, util.Errorf("got %d values but expected %d", len(updateValues), len(ru.updateCols)) } primaryIndexKey, secondaryIndexEntries, err := ru.helper.encodeIndexes(ru.fetchColIDtoRowIndex, oldValues) if err != nil { return nil, err } // Check that the new value types match the column types. This needs to // happen before index encoding because certain datum types (i.e. tuple) // cannot be used as index values. for i, val := range updateValues { if ru.marshalled[i], err = sqlbase.MarshalColumnValue(ru.updateCols[i], val); err != nil { return nil, err } } // Update the row values. copy(ru.newValues, oldValues) for i, updateCol := range ru.updateCols { ru.newValues[ru.fetchColIDtoRowIndex[updateCol.ID]] = updateValues[i] } newPrimaryIndexKey := primaryIndexKey rowPrimaryKeyChanged := false var newSecondaryIndexEntries []sqlbase.IndexEntry if ru.primaryKeyColChange { newPrimaryIndexKey, newSecondaryIndexEntries, err = ru.helper.encodeIndexes(ru.fetchColIDtoRowIndex, ru.newValues) if err != nil { return nil, err } rowPrimaryKeyChanged = !bytes.Equal(primaryIndexKey, newPrimaryIndexKey) } else { newSecondaryIndexEntries, err = sqlbase.EncodeSecondaryIndexes( ru.helper.tableDesc.ID, ru.helper.indexes, ru.fetchColIDtoRowIndex, ru.newValues) if err != nil { return nil, err } } if rowPrimaryKeyChanged { err := ru.rd.deleteRow(b, oldValues) if err != nil { return nil, err } err = ru.ri.insertRow(b, ru.newValues) return ru.newValues, err } // Update secondary indexes. for i, newSecondaryIndexEntry := range newSecondaryIndexEntries { secondaryIndexEntry := secondaryIndexEntries[i] secondaryKeyChanged := !bytes.Equal(newSecondaryIndexEntry.Key, secondaryIndexEntry.Key) if secondaryKeyChanged { if log.V(2) { log.Infof("Del %s", secondaryIndexEntry.Key) } b.Del(secondaryIndexEntry.Key) // Do not update Indexes in the DELETE_ONLY state. if _, ok := ru.deleteOnlyIndex[i]; !ok { if log.V(2) { log.Infof("CPut %s -> %v", newSecondaryIndexEntry.Key, newSecondaryIndexEntry.Value) } b.CPut(newSecondaryIndexEntry.Key, newSecondaryIndexEntry.Value, nil) } } } // Add the new values. for i, val := range updateValues { col := ru.updateCols[i] if ru.helper.columnInPK(col.ID) { // Skip primary key columns as their values are encoded in the row // sentinel key which is guaranteed to exist for as long as the row // exists. continue } ru.key = keys.MakeColumnKey(newPrimaryIndexKey, uint32(col.ID)) if ru.marshalled[i].RawBytes != nil { // We only output non-NULL values. Non-existent column keys are // considered NULL during scanning and the row sentinel ensures we know // the row exists. if log.V(2) { log.Infof("Put %s -> %v", ru.key, val) } b.Put(&ru.key, &ru.marshalled[i]) } else { // The column might have already existed but is being set to NULL, so // delete it. if log.V(2) { log.Infof("Del %s", ru.key) } b.Del(&ru.key) } ru.key = nil } return ru.newValues, nil }
// 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 }
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 { 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 { if log.V(2) { log.Infof("CPut %s -> %v", secondaryIndexEntry.key, secondaryIndexEntry.value) } b.CPut(secondaryIndexEntry.key, secondaryIndexEntry.value, nil) } } } return rows.Err() } return nil }
// Update updates columns for a selection of rows from a table. // Privileges: UPDATE and SELECT on table. We currently always use a select statement. // Notes: postgres requires UPDATE. Requires SELECT with WHERE clause with table. // mysql requires UPDATE. Also requires SELECT with WHERE clause with table. func (p *planner) Update(n *parser.Update) (planNode, *roachpb.Error) { tableDesc, pErr := p.getAliasedTableLease(n.Table) if pErr != nil { return nil, pErr } if err := p.checkPrivilege(tableDesc, privilege.UPDATE); err != nil { return nil, roachpb.NewError(err) } // Determine which columns we're inserting into. var names parser.QualifiedNames for _, expr := range n.Exprs { var epErr *roachpb.Error expr.Expr, epErr = p.expandSubqueries(expr.Expr, len(expr.Names)) if epErr != nil { return nil, epErr } if expr.Tuple { // TODO(pmattis): The distinction between Tuple and DTuple here is // irritating. We'll see a DTuple if the expression was a subquery that // has been evaluated. We'll see a Tuple in other cases. n := 0 switch t := expr.Expr.(type) { case parser.Tuple: n = len(t) case parser.DTuple: n = len(t) default: return nil, roachpb.NewErrorf("unsupported tuple assignment: %T", expr.Expr) } if len(expr.Names) != n { return nil, roachpb.NewUErrorf("number of columns (%d) does not match number of values (%d)", len(expr.Names), n) } } names = append(names, expr.Names...) } cols, err := p.processColumns(tableDesc, names) if err != nil { return nil, roachpb.NewError(err) } // Set of columns being updated colIDSet := map[ColumnID]struct{}{} for _, c := range cols { colIDSet[c.ID] = struct{}{} } // Don't allow updating any column that is part of the primary key. for i, id := range tableDesc.PrimaryIndex.ColumnIDs { if _, ok := colIDSet[id]; ok { return nil, roachpb.NewUErrorf("primary key column %q cannot be updated", tableDesc.PrimaryIndex.ColumnNames[i]) } } defaultExprs, err := p.makeDefaultExprs(cols) if err != nil { return nil, roachpb.NewError(err) } // Generate the list of select targets. We need to select all of the columns // plus we select all of the update expressions in case those expressions // reference columns (e.g. "UPDATE t SET v = v + 1"). Note that we flatten // expressions for tuple assignments just as we flattened the column names // above. So "UPDATE t SET (a, b) = (1, 2)" translates into select targets of // "*, 1, 2", not "*, (1, 2)". targets := tableDesc.allColumnsSelector() i := 0 for _, expr := range n.Exprs { if expr.Tuple { switch t := expr.Expr.(type) { case parser.Tuple: for _, e := range t { e = fillDefault(e, i, defaultExprs) targets = append(targets, parser.SelectExpr{Expr: e}) i++ } case parser.DTuple: for _, e := range t { targets = append(targets, parser.SelectExpr{Expr: e}) i++ } } } else { e := fillDefault(expr.Expr, i, defaultExprs) targets = append(targets, parser.SelectExpr{Expr: e}) i++ } } // Query the rows that need updating. rows, pErr := p.Select(&parser.Select{ Exprs: targets, From: parser.TableExprs{n.Table}, Where: n.Where, }) if pErr != nil { return nil, pErr } // ValArgs have their types populated in the above Select if they are part // of an expression ("SET a = 2 + $1") in the type check step where those // types are inferred. For the simpler case ("SET a = $1"), populate them // using marshalColumnValue. This step also verifies that the expression // types match the column types. if p.prepareOnly { i := 0 f := func(expr parser.Expr) *roachpb.Error { idx := i i++ // DefaultVal doesn't implement TypeCheck if _, ok := expr.(parser.DefaultVal); ok { return nil } d, err := expr.TypeCheck(p.evalCtx.Args) if err != nil { return roachpb.NewError(err) } if _, err := marshalColumnValue(cols[idx], d, p.evalCtx.Args); err != nil { return roachpb.NewError(err) } return nil } for _, expr := range n.Exprs { if expr.Tuple { switch t := expr.Expr.(type) { case parser.Tuple: for _, e := range t { if err := f(e); err != nil { return nil, err } } case parser.DTuple: for _, e := range t { if err := f(e); err != nil { return nil, err } } } } else { if err := f(expr.Expr); err != nil { return nil, err } } } return nil, nil } // Construct a map from column ID to the index the value appears at within a // row. colIDtoRowIndex := map[ColumnID]int{} for i, col := range tableDesc.Columns { colIDtoRowIndex[col.ID] = i } primaryIndex := tableDesc.PrimaryIndex primaryIndexKeyPrefix := MakeIndexKeyPrefix(tableDesc.ID, primaryIndex.ID) // Secondary indexes needing updating. needsUpdate := func(index IndexDescriptor) bool { for _, id := range index.ColumnIDs { if _, ok := colIDSet[id]; ok { return true } } return false } indexes := make([]IndexDescriptor, 0, len(tableDesc.Indexes)+len(tableDesc.Mutations)) var deleteOnlyIndex map[int]struct{} for _, index := range tableDesc.Indexes { if needsUpdate(index) { indexes = append(indexes, index) } } for _, m := range tableDesc.Mutations { if index := m.GetIndex(); index != nil { if needsUpdate(*index) { indexes = append(indexes, *index) switch m.State { case DescriptorMutation_DELETE_ONLY: if deleteOnlyIndex == nil { // Allocate at most once. deleteOnlyIndex = make(map[int]struct{}, len(tableDesc.Mutations)) } deleteOnlyIndex[len(indexes)-1] = struct{}{} case DescriptorMutation_WRITE_ONLY: } } } } marshalled := make([]interface{}, len(cols)) 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) } // Compute the current secondary index key:value pairs for this row. secondaryIndexEntries, err := encodeSecondaryIndexes( tableDesc.ID, indexes, colIDtoRowIndex, rowVals) if err != nil { return nil, roachpb.NewError(err) } // Our updated value expressions occur immediately after the plain // columns in the output. newVals := rowVals[len(tableDesc.Columns):] // Update the row values. for i, col := range cols { val := newVals[i] if !col.Nullable && val == parser.DNull { return nil, roachpb.NewUErrorf("null value in column %q violates not-null constraint", col.Name) } rowVals[colIDtoRowIndex[col.ID]] = val } // Check that the new value types match the column types. This needs to // happen before index encoding because certain datum types (i.e. tuple) // cannot be used as index values. for i, val := range newVals { var mErr error if marshalled[i], mErr = marshalColumnValue(cols[i], val, p.evalCtx.Args); mErr != nil { return nil, roachpb.NewError(mErr) } } // Compute the new secondary index key:value pairs for this row. newSecondaryIndexEntries, eErr := encodeSecondaryIndexes( tableDesc.ID, indexes, colIDtoRowIndex, rowVals) if eErr != nil { return nil, roachpb.NewError(eErr) } // Update secondary indexes. for i, newSecondaryIndexEntry := range newSecondaryIndexEntries { secondaryIndexEntry := secondaryIndexEntries[i] if !bytes.Equal(newSecondaryIndexEntry.key, secondaryIndexEntry.key) { // Do not update Indexes in the DELETE_ONLY state. if _, ok := deleteOnlyIndex[i]; !ok { if log.V(2) { log.Infof("CPut %s -> %v", newSecondaryIndexEntry.key, newSecondaryIndexEntry.value) } b.CPut(newSecondaryIndexEntry.key, newSecondaryIndexEntry.value, nil) } if log.V(2) { log.Infof("Del %s", secondaryIndexEntry.key) } b.Del(secondaryIndexEntry.key) } } // Add the new values. for i, val := range newVals { col := cols[i] key := keys.MakeColumnKey(primaryIndexKey, uint32(col.ID)) if marshalled[i] != nil { // We only output non-NULL values. Non-existent column keys are // considered NULL during scanning and the row sentinel ensures we know // the row exists. if log.V(2) { log.Infof("Put %s -> %v", key, val) } b.Put(key, marshalled[i]) } else { // The column might have already existed but is being set to NULL, so // delete it. if log.V(2) { log.Infof("Del %s", key) } b.Del(key) } } } if pErr := rows.PErr(); pErr != nil { return nil, pErr } if pErr := p.txn.Run(&b); pErr != nil { return nil, convertBatchError(tableDesc, b, pErr) } return result, nil }
func delMeta(b *client.Batch, key proto.Key, desc *proto.RangeDescriptor) { b.Del(key) }
// Update updates columns for a selection of rows from a table. // Privileges: WRITE and READ on table. We currently always use a select statement. // Notes: postgres requires UPDATE. Requires SELECT with WHERE clause with table. // mysql requires UPDATE. Also requires SELECT with WHERE clause with table. func (p *planner) Update(n *parser.Update) (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) } // Determine which columns we're inserting into. var names parser.QualifiedNames for _, expr := range n.Exprs { names = append(names, expr.Name) } cols, err := p.processColumns(tableDesc, names) if err != nil { return nil, err } // Set of columns being updated colIDSet := map[structured.ColumnID]struct{}{} for _, c := range cols { colIDSet[c.ID] = struct{}{} } // Don't allow updating any column that is part of the primary key. for i, id := range tableDesc.PrimaryIndex.ColumnIDs { if _, ok := colIDSet[id]; ok { return nil, fmt.Errorf("primary key column %q cannot be updated", tableDesc.PrimaryIndex.ColumnNames[i]) } } // Query the rows that need updating. // TODO(vivek): Avoid going through Select. row, 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[structured.ColumnID]int{} for i, name := range row.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) // Evaluate all the column value expressions. vals := make([]parser.Datum, 0, 10) for _, expr := range n.Exprs { val, err := parser.EvalExpr(expr.Expr) if err != nil { return nil, err } vals = append(vals, val) } // Secondary indexes needing updating. var indexes []structured.IndexDescriptor for _, index := range tableDesc.Indexes { for _, id := range index.ColumnIDs { if _, ok := colIDSet[id]; ok { indexes = append(indexes, index) break } } } // Update all the rows. b := client.Batch{} for row.Next() { rowVals := row.Values() primaryIndexKeySuffix, _, err := encodeIndexKey(primaryIndex.ColumnIDs, colIDtoRowIndex, rowVals, nil) if err != nil { return nil, err } primaryIndexKey := bytes.Join([][]byte{primaryIndexKeyPrefix, primaryIndexKeySuffix}, nil) // Compute the current secondary index key:value pairs for this row. secondaryIndexEntries, err := encodeSecondaryIndexes(tableDesc.ID, indexes, colIDtoRowIndex, rowVals, primaryIndexKeySuffix) if err != nil { return nil, err } // Compute the new secondary index key:value pairs for this row. // // Update the row values. for i, col := range cols { val := vals[i] if !col.Nullable && val == parser.DNull { return nil, fmt.Errorf("null value in column %q violates not-null constraint", col.Name) } rowVals[colIDtoRowIndex[col.ID]] = val } newSecondaryIndexEntries, err := encodeSecondaryIndexes(tableDesc.ID, indexes, colIDtoRowIndex, rowVals, primaryIndexKeySuffix) if err != nil { return nil, err } // Update secondary indexes. for i, newSecondaryIndexEntry := range newSecondaryIndexEntries { secondaryIndexEntry := secondaryIndexEntries[i] if !bytes.Equal(newSecondaryIndexEntry.key, secondaryIndexEntry.key) { if log.V(2) { log.Infof("CPut %q -> %v", newSecondaryIndexEntry.key, newSecondaryIndexEntry.value) } b.CPut(newSecondaryIndexEntry.key, newSecondaryIndexEntry.value, nil) if log.V(2) { log.Infof("Del %q", secondaryIndexEntry.key) } b.Del(secondaryIndexEntry.key) } } // Add the new values. for i, val := range vals { col := cols[i] primitive, err := convertDatum(col, val) if err != nil { return nil, err } key := structured.MakeColumnKey(col.ID, primaryIndexKey) if primitive != nil { // We only output non-NULL values. Non-existent column keys are // considered NULL during scanning and the row sentinel ensures we know // the row exists. if log.V(2) { log.Infof("Put %q -> %v", key, val) } b.Put(key, primitive) } else { // The column might have already existed but is being set to NULL, so // delete it. if log.V(2) { log.Infof("Del %q", key) } b.Del(key) } } } if err := row.Err(); err != nil { return nil, err } if err := p.txn.Run(&b); err != nil { if tErr, ok := err.(*proto.ConditionFailedError); ok { return nil, fmt.Errorf("duplicate key value %q violates unique constraint %s", tErr.ActualValue.Bytes, "TODO(tamird)") } return nil, err } // TODO(tamird/pmattis): return the number of affected rows. return &valuesNode{}, nil }
// 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) 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. node, 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 node.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{} for node.Next() { values := node.Values() primaryIndexKey, _, err := encodeIndexKey( primaryIndex.ColumnIDs, colIDtoRowIndex, values, primaryIndexKeyPrefix) if err != nil { return nil, err } // Delete the secondary indexes. secondaryIndexEntries, err := encodeSecondaryIndexes( tableDesc.ID, tableDesc.Indexes, colIDtoRowIndex, values) 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 := node.Err(); err != nil { return nil, err } if err := p.txn.Run(&b).GoError(); err != nil { return nil, err } // TODO(tamird/pmattis): return the number of affected rows return &valuesNode{}, nil }
func delMeta(b *client.Batch, key roachpb.Key, desc *roachpb.RangeDescriptor) { b.Del(key) }
// Update updates columns for a selection of rows from a table. // Privileges: UPDATE and SELECT on table. We currently always use a select statement. // Notes: postgres requires UPDATE. Requires SELECT with WHERE clause with table. // mysql requires UPDATE. Also requires SELECT with WHERE clause with table. func (p *planner) Update(n *parser.Update) (planNode, error) { tableDesc, err := p.getAliasedTableDesc(n.Table) if err != nil { return nil, err } if err := p.checkPrivilege(tableDesc, privilege.UPDATE); err != nil { return nil, err } // Determine which columns we're inserting into. var names parser.QualifiedNames for _, expr := range n.Exprs { var err error expr.Expr, err = p.expandSubqueries(expr.Expr, len(expr.Names)) if err != nil { return nil, err } if expr.Tuple { // TODO(pmattis): The distinction between Tuple and DTuple here is // irritating. We'll see a DTuple if the expression was a subquery that // has been evaluated. We'll see a Tuple in other cases. n := 0 switch t := expr.Expr.(type) { case parser.Tuple: n = len(t) case parser.DTuple: n = len(t) default: return nil, util.Errorf("unsupported tuple assignment: %T", expr.Expr) } if len(expr.Names) != n { return nil, fmt.Errorf("number of columns (%d) does not match number of values (%d)", len(expr.Names), n) } } names = append(names, expr.Names...) } cols, err := p.processColumns(tableDesc, names) if err != nil { return nil, err } // Set of columns being updated colIDSet := map[ColumnID]struct{}{} for _, c := range cols { colIDSet[c.ID] = struct{}{} } // Don't allow updating any column that is part of the primary key. for i, id := range tableDesc.PrimaryIndex.ColumnIDs { if _, ok := colIDSet[id]; ok { return nil, fmt.Errorf("primary key column %q cannot be updated", tableDesc.PrimaryIndex.ColumnNames[i]) } } defaultExprs, err := p.makeDefaultExprs(cols) if err != nil { return nil, err } // Generate the list of select targets. We need to select all of the columns // plus we select all of the update expressions in case those expressions // reference columns (e.g. "UPDATE t SET v = v + 1"). Note that we flatten // expressions for tuple assignments just as we flattened the column names // above. So "UPDATE t SET (a, b) = (1, 2)" translates into select targets of // "*, 1, 2", not "*, (1, 2)". targets := make(parser.SelectExprs, 0, len(n.Exprs)+1) targets = append(targets, parser.StarSelectExpr()) for _, expr := range n.Exprs { if expr.Tuple { switch t := expr.Expr.(type) { case parser.Tuple: for i, e := range t { e, err := fillDefault(e, i, defaultExprs) if err != nil { return nil, err } targets = append(targets, parser.SelectExpr{Expr: e}) } case parser.DTuple: for _, e := range t { targets = append(targets, parser.SelectExpr{Expr: e}) } } } else { e, err := fillDefault(expr.Expr, 0, defaultExprs) if err != nil { return nil, err } targets = append(targets, parser.SelectExpr{Expr: e}) } } // Query the rows that need updating. rows, err := p.Select(&parser.Select{ Exprs: targets, 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, col := range tableDesc.Columns { colIDtoRowIndex[col.ID] = i } primaryIndex := tableDesc.PrimaryIndex primaryIndexKeyPrefix := MakeIndexKeyPrefix(tableDesc.ID, primaryIndex.ID) // Secondary indexes needing updating. var indexes []IndexDescriptor for _, index := range tableDesc.Indexes { for _, id := range index.ColumnIDs { if _, ok := colIDSet[id]; ok { indexes = append(indexes, index) break } } } marshalled := make([]interface{}, len(cols)) // Update all the rows. var b client.Batch for rows.Next() { rowVals := rows.Values() primaryIndexKey, _, err := encodeIndexKey( primaryIndex.ColumnIDs, colIDtoRowIndex, rowVals, primaryIndexKeyPrefix) if err != nil { return nil, err } // Compute the current secondary index key:value pairs for this row. secondaryIndexEntries, err := encodeSecondaryIndexes( tableDesc.ID, indexes, colIDtoRowIndex, rowVals) if err != nil { return nil, err } // Our updated value expressions occur immediately after the plain // columns in the output. newVals := rowVals[len(tableDesc.Columns):] // Update the row values. for i, col := range cols { val := newVals[i] if !col.Nullable && val == parser.DNull { return nil, fmt.Errorf("null value in column %q violates not-null constraint", col.Name) } rowVals[colIDtoRowIndex[col.ID]] = val } // Check that the new value types match the column types. This needs to // happen before index encoding because certain datum types (i.e. tuple) // cannot be used as index values. for i, val := range newVals { var err error if marshalled[i], err = marshalColumnValue(cols[i], val); err != nil { return nil, err } } // Compute the new secondary index key:value pairs for this row. newSecondaryIndexEntries, err := encodeSecondaryIndexes( tableDesc.ID, indexes, colIDtoRowIndex, rowVals) if err != nil { return nil, err } // Update secondary indexes. for i, newSecondaryIndexEntry := range newSecondaryIndexEntries { secondaryIndexEntry := secondaryIndexEntries[i] if !bytes.Equal(newSecondaryIndexEntry.key, secondaryIndexEntry.key) { if log.V(2) { log.Infof("CPut %q -> %v", newSecondaryIndexEntry.key, newSecondaryIndexEntry.value) } b.CPut(newSecondaryIndexEntry.key, newSecondaryIndexEntry.value, nil) if log.V(2) { log.Infof("Del %q", secondaryIndexEntry.key) } b.Del(secondaryIndexEntry.key) } } // Add the new values. for i, val := range newVals { col := cols[i] key := MakeColumnKey(col.ID, primaryIndexKey) if marshalled[i] != nil { // We only output non-NULL values. Non-existent column keys are // considered NULL during scanning and the row sentinel ensures we know // the row exists. if log.V(2) { log.Infof("Put %q -> %v", key, val) } b.Put(key, marshalled[i]) } else { // The column might have already existed but is being set to NULL, so // delete it. if log.V(2) { log.Infof("Del %q", key) } b.Del(key) } } } if err := rows.Err(); err != nil { return nil, err } if err := p.txn.Run(&b); err != nil { return nil, convertBatchError(tableDesc, b, err) } // TODO(tamird/pmattis): return the number of affected rows. return &valuesNode{}, nil }
// 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. 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, err := makeColIDtoRowIndex(rows, tableDesc) if err != nil { return nil, 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.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 IsSystemID(tableDesc.GetID()) { // Mark transaction as operating on the system DB. p.txn.SetSystemDBTrigger() } if err := p.txn.Run(&b); err != nil { return nil, err } return result, nil }
// 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 }
// Execute the entire schema change in steps. startBackfillNotification is // called before the backfill starts; it can be nil. func (sc SchemaChanger) exec( startBackfillNotification func() error, oldNameNotInUseNotification func(), ) error { // Acquire lease. lease, err := sc.AcquireLease() if err != nil { return err } needRelease := true // Always try to release lease. defer func(l *sqlbase.TableDescriptor_SchemaChangeLease) { // If the schema changer deleted the descriptor, there's no longer a lease to be // released. if !needRelease { return } if err := sc.ReleaseLease(*l); err != nil { log.Warning(err) } }(&lease) // Increment the version and unset tableDescriptor.UpVersion. desc, err := sc.MaybeIncrementVersion() if err != nil { return err } if desc.GetTable().Deleted() { lease, err = sc.ExtendLease(lease) if err != nil { return err } // Wait for everybody to see the version with the deleted bit set. When // this returns, nobody has any leases on the table, nor can get new leases, // so the table will no longer be modified. if err := sc.waitToUpdateLeases(); err != nil { return err } // Truncate the table and delete the descriptor. if err := sc.truncateAndDropTable(&lease, desc.GetTable()); err != nil { return err } needRelease = false return nil } if desc.GetTable().Renamed() { lease, err = sc.ExtendLease(lease) if err != nil { return err } // Wait for everyone to see the version with the new name. When this // returns, no new transactions will be using the old name for the table, so // the old name can now be re-used (by CREATE). if err := sc.waitToUpdateLeases(); err != nil { return err } if oldNameNotInUseNotification != nil { oldNameNotInUseNotification() } // Free up the old name(s). err := sc.db.Txn(func(txn *client.Txn) error { b := client.Batch{} for _, renameDetails := range desc.GetTable().Renames { tbKey := tableKey{ sqlbase.ID(renameDetails.OldParentID), renameDetails.OldName}.Key() b.Del(tbKey) } if err := txn.Run(&b); err != nil { return err } return nil }) if err != nil { return err } // Clean up - clear the descriptor's state. _, err = sc.leaseMgr.Publish(sc.tableID, func(desc *sqlbase.TableDescriptor) error { desc.Renames = nil return nil }) if err != nil { return err } } // Wait for the schema change to propagate to all nodes after this function // returns, so that the new schema is live everywhere. This is not needed for // correctness but is done to make the UI experience/tests predictable. defer func() { if err := sc.waitToUpdateLeases(); err != nil { log.Warning(err) } }() if sc.mutationID == sqlbase.InvalidMutationID { // Nothing more to do. return nil } // Another transaction might set the up_version bit again, // but we're no longer responsible for taking care of that. // Run through mutation state machine and backfill. err = sc.runStateMachineAndBackfill(&lease, startBackfillNotification) // Purge the mutations if the application of the mutations failed due to // an integrity constraint violation. All other errors are transient // errors that are resolved by retrying the backfill. if sqlbase.IsIntegrityConstraintError(err) { log.Warningf("reversing schema change due to irrecoverable error: %s", err) if errReverse := sc.reverseMutations(); errReverse != nil { // Although the backfill did hit an integrity constraint violation // and made a decision to reverse the mutations, // reverseMutations() failed. If exec() is called again the entire // schema change will be retried. return errReverse } // After this point the schema change has been reversed and any retry // of the schema change will act upon the reversed schema change. if errPurge := sc.runStateMachineAndBackfill( &lease, startBackfillNotification, ); errPurge != nil { // Don't return this error because we do want the caller to know // that an integrity constraint was violated with the original // schema change. The reversed schema change will be // retried via the async schema change manager. log.Warningf("error purging mutation: %s, after error: %s", errPurge, err) } } return err }
// RenameTable renames the table. // Privileges: DROP on source table, CREATE on destination database. // Notes: postgres requires the table owner. // mysql requires ALTER, DROP on the original table, and CREATE, INSERT // on the new table (and does not copy privileges over). func (p *planner) RenameTable(n *parser.RenameTable) (planNode, error) { if err := n.NewName.NormalizeTableName(p.session.Database); err != nil { return nil, err } if n.NewName.Table() == "" { return nil, errEmptyTableName } if err := n.Name.NormalizeTableName(p.session.Database); err != nil { return nil, err } dbDesc, err := p.getDatabaseDesc(n.Name.Database()) if err != nil { return nil, err } tbKey := tableKey{dbDesc.ID, n.Name.Table()}.Key() // Check if table exists. gr, err := p.txn.Get(tbKey) if err != nil { return nil, err } if !gr.Exists() { if n.IfExists { // Noop. return &valuesNode{}, nil } // Key does not exist, but we want it to: error out. return nil, fmt.Errorf("table %q does not exist", n.Name.Table()) } targetDbDesc, err := p.getDatabaseDesc(n.NewName.Database()) if err != nil { return nil, err } if err := p.checkPrivilege(targetDbDesc, privilege.CREATE); err != nil { return nil, err } if n.Name.Database() == n.NewName.Database() && n.Name.Table() == n.NewName.Table() { // Noop. return &valuesNode{}, nil } tableDesc, err := p.getTableDesc(n.Name) if err != nil { return nil, err } if err := p.checkPrivilege(tableDesc, privilege.DROP); err != nil { return nil, err } tableDesc.SetName(n.NewName.Table()) tableDesc.ParentID = targetDbDesc.ID newTbKey := tableKey{targetDbDesc.ID, n.NewName.Table()}.Key() descKey := MakeDescMetadataKey(tableDesc.GetID()) if err := tableDesc.Validate(); err != nil { return nil, err } b := client.Batch{} b.Put(descKey, tableDesc) b.CPut(newTbKey, tableDesc.GetID(), nil) b.Del(tbKey) // Mark transaction as operating on the system DB. p.txn.SetSystemDBTrigger() if err := p.txn.Run(&b); err != nil { if _, ok := err.(*proto.ConditionFailedError); ok { return nil, fmt.Errorf("table name %q already exists", n.NewName.Table()) } return nil, err } return &valuesNode{}, nil }
// 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 }