func encodeEndConstraintDescending( spans []roachpb.Span, c *parser.ComparisonExpr, isLastEndConstraint bool, ) { switch c.Operator { case parser.IsNot: // An IS NOT NULL expressions allows us to constrain the end of the range // to stop at NULL. if c.Right != parser.DNull { panic(fmt.Sprintf("expected NULL operand for IS NOT operator, found %v", c.Right)) } for i := range spans { spans[i].EndKey = encoding.EncodeNotNullDescending(spans[i].EndKey) } default: datum := c.Right.(parser.Datum) if c.Operator != parser.GT { for i := range spans { spans[i].EndKey = encodeInclusiveEndValue( spans[i].EndKey, datum, encoding.Descending, isLastEndConstraint) } break } if !isLastEndConstraint { panic(fmt.Sprintf("can't have other end constraints after a '>' constraint, found %v", c.Operator)) } key, err := sqlbase.EncodeTableKey(nil, datum, encoding.Descending) if err != nil { panic(err) } // Append the constraint to all of the existing spans. for i := range spans { spans[i].EndKey = append(spans[i].EndKey, key...) } } }
// deleteRow adds to the batch the kv operations necessary to delete a table row // with the given values. func (rd *rowDeleter) deleteRow(ctx context.Context, 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(ctx, "Del %s", secondaryIndexEntry.Key) } b.Del(secondaryIndexEntry.Key) } // Delete the row. rd.startKey = roachpb.Key(primaryIndexKey) rd.endKey = roachpb.Key(encoding.EncodeNotNullDescending(primaryIndexKey)) if log.V(2) { log.Infof(ctx, "DelRange %s - %s", rd.startKey, rd.endKey) } b.DelRange(&rd.startKey, &rd.endKey, false) rd.startKey, rd.endKey = nil, nil return nil }
// MakeKeyFromEncDatums creates a key by concatenating keyPrefix with the // encodings of the given EncDatum values. The values correspond to // index.ColumnIDs. // // If a table or index is interleaved, `encoding.encodedNullDesc` is used in // place of the family id (a varint) to signal the next component of the key. // An example of one level of interleaving (a parent): // /<parent_table_id>/<parent_index_id>/<field_1>/<field_2>/NullDesc/<table_id>/<index_id>/<field_3>/<family> // // Note that ImplicitColumnIDs are not encoded, so the result isn't always a // full index key. func MakeKeyFromEncDatums( values EncDatumRow, tableDesc *TableDescriptor, index *IndexDescriptor, keyPrefix []byte, alloc *DatumAlloc, ) (roachpb.Key, error) { dirs := index.ColumnDirections if len(values) != len(dirs) { return nil, errors.Errorf("%d values, %d directions", len(values), len(dirs)) } // We know we will append to the key which will cause the capacity to grow // so make it bigger from the get-go. key := make(roachpb.Key, len(keyPrefix), len(keyPrefix)*2) copy(key, keyPrefix) if len(index.Interleave.Ancestors) > 0 { for i, ancestor := range index.Interleave.Ancestors { // The first ancestor is assumed to already be encoded in keyPrefix. if i != 0 { key = encoding.EncodeUvarintAscending(key, uint64(ancestor.TableID)) key = encoding.EncodeUvarintAscending(key, uint64(ancestor.IndexID)) } length := int(ancestor.SharedPrefixLen) var err error key, err = appendEncDatumsToKey(key, values[:length], dirs[:length], alloc) if err != nil { return nil, err } values, dirs = values[length:], dirs[length:] // We reuse NotNullDescending (0xfe) as the interleave sentinel. key = encoding.EncodeNotNullDescending(key) } key = encoding.EncodeUvarintAscending(key, uint64(tableDesc.ID)) key = encoding.EncodeUvarintAscending(key, uint64(index.ID)) } return appendEncDatumsToKey(key, values, dirs, alloc) }
// EncodeIndexKey creates a key by concatenating keyPrefix with the encodings of // the columns in the index. // // If a table or index is interleaved, `encoding.encodedNullDesc` is used in // place of the family id (a varint) to signal the next component of the key. // An example of one level of interleaving (a parent): // /<parent_table_id>/<parent_index_id>/<field_1>/<field_2>/NullDesc/<table_id>/<index_id>/<field_3>/<family> // // Returns the key and whether any of the encoded values were NULLs. // // Note that ImplicitColumnIDs are not encoded, so the result isn't always a // full index key. func EncodeIndexKey( tableDesc *TableDescriptor, index *IndexDescriptor, colMap map[ColumnID]int, values []parser.Datum, keyPrefix []byte, ) (key []byte, containsNull bool, err error) { key = keyPrefix colIDs := index.ColumnIDs dirs := directions(index.ColumnDirections) if len(index.Interleave.Ancestors) > 0 { for i, ancestor := range index.Interleave.Ancestors { // The first ancestor is assumed to already be encoded in keyPrefix. if i != 0 { key = encoding.EncodeUvarintAscending(key, uint64(ancestor.TableID)) key = encoding.EncodeUvarintAscending(key, uint64(ancestor.IndexID)) } length := int(ancestor.SharedPrefixLen) var n bool key, n, err = EncodeColumns(colIDs[:length], dirs[:length], colMap, values, key) if err != nil { return key, containsNull, err } colIDs, dirs = colIDs[length:], dirs[length:] containsNull = containsNull || n // We reuse NotNullDescending (0xfe) as the interleave sentinel. key = encoding.EncodeNotNullDescending(key) } key = encoding.EncodeUvarintAscending(key, uint64(tableDesc.ID)) key = encoding.EncodeUvarintAscending(key, uint64(index.ID)) } var n bool key, n, err = EncodeColumns(colIDs, dirs, colMap, values, key) containsNull = containsNull || n return key, containsNull, err }