code: func (c *index) GenIndexKey(sc *stmtctx.StatementContext, indexedValues []types.Datum, h int64, buf []byte) (key []byte, distinct bool, err error) {
  	if c.idxInfo.Unique {
  		// See https://dev.mysql.com/doc/refman/5.7/en/create-index.html
  		// A UNIQUE index creates a constraint such that all values in the index must be distinct.
  		// An error occurs if you try to add a new row with a key value that matches an existing row.
  		// For all engines, a UNIQUE index permits multiple NULL values for columns that can contain NULL.
  		distinct = true
  		for _, cv := range indexedValues {
  			if cv.IsNull() {
  				distinct = false
  				break
  			}
  		}
  	}
  
  	// For string columns, indexes can be created using only the leading part of column values,
  	// using col_name(length) syntax to specify an index prefix length.
  	indexedValues = TruncateIndexValuesIfNeeded(c.tblInfo, c.idxInfo, indexedValues)
  	key = c.getIndexKeyBuf(buf, len(c.prefix)+len(indexedValues)*9+9)
  	key = append(key, []byte(c.prefix)...)
  	key, err = codec.EncodeKey(sc, key, indexedValues...)
  	if !distinct && err == nil {
  		key, err = codec.EncodeKey(sc, key, types.NewDatum(h))
  	}
  	if err != nil {
  		return nil, false, err
  	}
  	return
  }
docs: // GenIndexKey generates storage key for index values. Returned distinct indicates whether the
  // indexed values should be distinct in storage (i.e. whether handle is encoded in the key).