code: func (e *HashJoinExec) buildGlobalHashTable() error {
  	e.globalHashTable = mvmap.NewMVMap()
  	var (
  		hasNull bool
  		err     error
  		keyBuf  = make([]byte, 0, 64)
  		valBuf  = make([]byte, 8)
  	)
  
  	for chkIdx := 0; chkIdx < e.innerResult.NumChunks(); chkIdx++ {
  		if e.finished.Load().(bool) {
  			return nil
  		}
  		chk := e.innerResult.GetChunk(chkIdx)
  		for j, numRows := 0, chk.NumRows(); j < numRows; j++ {
  			hasNull, keyBuf, err = e.getJoinKeyFromChkRow(false, chk.GetRow(j), keyBuf)
  			if err != nil {
  				return err
  			}
  			if hasNull {
  				continue
  			}
  			rowPtr := chunk.RowPtr{ChkIdx: uint32(chkIdx), RowIdx: uint32(j)}
  			*(*chunk.RowPtr)(unsafe.Pointer(&valBuf[0])) = rowPtr
  			e.globalHashTable.Put(keyBuf, valBuf)
  		}
  	}
  	return nil
  }
docs: // buildGlobalHashTable builds a global hash table for the inner relation.
  // key of hash table: hash value of key columns
  // value of hash table: RowPtr of the corresponded row