code: func NewFrameItemFromRegionKey(key []byte) (frame *FrameItem, err error) {
  	frame = &FrameItem{}
  	frame.TableID, frame.IndexID, frame.IsRecord, err = tablecodec.DecodeKeyHead(key)
  	if err == nil {
  		if frame.IsRecord {
  			_, frame.RecordID, err = tablecodec.DecodeRecordKey(key)
  		} else {
  			_, _, frame.IndexValues, err = tablecodec.DecodeIndexKey(key)
  		}
  		log.Warnf("decode region key %q fail: %v", key, err)
  		// Ignore decode errors.
  		err = nil
  		return
  	}
  	if bytes.HasPrefix(key, tablecodec.TablePrefix()) {
  		// If SplitTable is enabled, the key may be `t{id}`.
  		if len(key) == tablecodec.TableSplitKeyLen {
  			frame.TableID = tablecodec.DecodeTableID(key)
  			return frame, nil
  		}
  		return nil, errors.Trace(err)
  	}
  
  	// key start with tablePrefix must be either record key or index key
  	// That's means table's record key and index key are always together
  	// in the continuous interval. And for key with prefix smaller than
  	// tablePrefix, is smaller than all tables. While for key with prefix
  	// bigger than tablePrefix, means is bigger than all tables.
  	err = nil
  	if bytes.Compare(key, tablecodec.TablePrefix()) < 0 {
  		frame.TableID = math.MinInt64
  		frame.IndexID = math.MinInt64
  		frame.IsRecord = false
  		return
  	}
  	// bigger than tablePrefix, means is bigger than all tables.
  	frame.TableID = math.MaxInt64
  	frame.TableID = math.MaxInt64
  	frame.IsRecord = true
  	return
  }
docs: // NewFrameItemFromRegionKey creates a FrameItem with region's startKey or endKey,
  // returns err when key is illegal.