func encodeEndConstraintDescending(spans []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].end = encoding.EncodeNotNullDescending(spans[i].end) } default: datum := c.Right.(parser.Datum) if c.Operator != parser.GT { for i := range spans { spans[i].end = encodeInclusiveEndValue( spans[i].end, 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 := 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].end = append(spans[i].end, key...) } } }
// 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 = roachpb.Key(encoding.EncodeNotNullDescending(primaryIndexKey)) 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 }
// 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 }
func encodeEndConstraintDescending(spans []span, c *parser.ComparisonExpr, isLastEndConstraint bool) { switch c.Operator { case parser.IsNot: // An IS NULL expressions allows us to constrain the end of the range // to stop at NULL. if c.Right != parser.DNull { panic("Expected NULL operand for IS NOT operator.") } for i := range spans { spans[i].end = encoding.EncodeNotNullDescending(spans[i].end) } case parser.GE, parser.EQ: datum := c.Right.(parser.Datum) for i := range spans { spans[i].end = encodeInclusiveEndValue( spans[i].end, datum, encoding.Descending, isLastEndConstraint) } case parser.GT: panic("'>' operators should have been transformed to '>='.") default: panic(fmt.Errorf("unexpected operator: %s", c.String())) } }